All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.jasperreports.engine.export.JRPdfExporterTagHelper Maven / Gradle / Ivy

There is a newer version: 6.21.3
Show newest version
/*
 * JasperReports - Free Java Reporting Library.
 * Copyright (C) 2001 - 2022 TIBCO Software Inc. All rights reserved.
 * http://www.jaspersoft.com
 *
 * Unless you have purchased a commercial license agreement from Jaspersoft,
 * the following license terms apply:
 *
 * This program is part of JasperReports.
 *
 * JasperReports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JasperReports is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with JasperReports. If not, see .
 */

/*
 * Contributors:
 * Adrian Jackson - [email protected]
 * David Taylor - [email protected]
 * Lars Kristensen - [email protected]
 * Ling Li - [email protected]
 * Martin Clough - [email protected]
 */
package net.sf.jasperreports.engine.export;

import java.util.Stack;

import net.sf.jasperreports.annotations.properties.Property;
import net.sf.jasperreports.annotations.properties.PropertyScope;
import net.sf.jasperreports.crosstabs.JRCellContents;
import net.sf.jasperreports.engine.JRPrintElement;
import net.sf.jasperreports.engine.JRPrintFrame;
import net.sf.jasperreports.engine.JRPrintImage;
import net.sf.jasperreports.engine.util.StyledTextListWriter;
import net.sf.jasperreports.export.AccessibilityUtil;
import net.sf.jasperreports.export.pdf.PdfProducer;
import net.sf.jasperreports.export.pdf.PdfStructure;
import net.sf.jasperreports.export.pdf.PdfStructureEntry;
import net.sf.jasperreports.export.type.AccessibilityTagEnum;
import net.sf.jasperreports.properties.PropertyConstants;


/**
 * Provides support for tagged PDF documents.
 * 

* PDF files can contain hidden tags that describe the structure of the document. Some of * the tags are used by the automated reader tool that reads PDF documents aloud to people * with disabilities. *

Marking Headings

* JasperReports currently supports specifying type 1, 2 and 3 level headings. * In order to mark a text field as a level 1 heading, the following custom element property * should be used in JRXML: *

* <property name="net.sf.jasperreports.export.pdf.tag.h1" value="full"/> *

* Value full means that a full <H1> tag will be embedded in the PDF wrapping the * current text element. * If two or more text fields make up a single level 1 heading, there are two ways to mark * the heading: *

    *
  • In the first, the text elements making up the heading are placed inside a frame and * the frame is marked with the following custom property: *
    * <property name="net.sf.jasperreports.export.pdf.tag.h1" value="full"/>
  • *
  • In the second, the first element of the heading (respective to the Z-Order, or the * order in which the elements appear in JRXML) is tagged with: *
    * <property name="net.sf.jasperreports.export.pdf.tag.h1" value="start"/> *
    * and the last element from the heading (respective to the same order) is marked with *
    * <property name="net.sf.jasperreports.export.pdf.tag.h1" value="end"/>
  • *
*

* Level 2 and level 3 headings are marked the same way, except that the properties are: *

* net.sf.jasperreports.export.pdf.tag.h2 *

* and *

* net.sf.jasperreports.export.pdf.tag.h3. *

Marking Tables

* Tables are comprised of column headers, row headers, and a data section. Each table * section is made of cells. Marking table structures in PDF is similar to the way tables are * described in HTML and uses the same techniques as those for marking headings. *

* When marking a table, the user has to indicate in the report template where the table * starts and where it ends. *

* If the entire table is placed in a container, such as a frame element, marking the table * requires only marking the parent frame with the following custom element property: *

* <property name="net.sf.jasperreports.export.pdf.tag.table" value="full"/> *

* However, most of the time, tables cannot be isolated in a frame unless they are * subreports, because they generally span multiple report sections and bands. In such * cases, marking a table requires marking in JRXML the first and last element making up * the table structure. *

* The first element of the table (probably the first element in the table header) should be * marked with the following custom property: *

* <property name="net.sf.jasperreports.export.pdf.tag.table" value="start"/> *

* The last element of the table should be marked with: *

* <property name="net.sf.jasperreports.export.pdf.tag.table" value="end"/> *

* Tables are made of rows, and each row has to be precisely delimited within the table * structure. This includes the column header rows at the top of the table. Similar to the * headings and table marking, a table row can be identified in two ways: *

    *
  • If the entire content that makes up the row is isolated within a frame, the frame can be * marked with the following custom property: *
    * <property name="net.sf.jasperreports.export.pdf.tag.tr" value="full"/> *
  • *
  • If the content of the row is not grouped in a container frame, its first and last elements * (respective to the Z-order or the order in which they appear in JRXML) have to be * marked with the following custom properties: *
    * <property name="net.sf.jasperreports.export.pdf.tag.tr" value="start"/> *
    * for the first element and *
    * <property name="net.sf.jasperreports.export.pdf.tag.tr" value="start"/> *
    * for the last element.
  • *
*

* Each table row can contain header cells or data cells. Regardless of their type, and * similar to headings, tables, and table rows, cells can be marked either by marking a * single element representing the cell content (this single cell element can actually be a * frame element), or by marking the first and last element from the cell content. *

* Header cells made of a single element (this single element can actually be a frame) are * marked with *

* <property name="net.sf.jasperreports.export.pdf.tag.th" value="full"/> *

* A header cell made of multiple elements is marked with *

* <property name="net.sf.jasperreports.export.pdf.tag.th" value="start"/> * on its first element and *

* <property name="net.sf.jasperreports.export.pdf.tag.th" value="end"/> * on its last element. *

* Normal data cells made of a single element (that can be frame) are marked with *

* <property name="net.sf.jasperreports.export.pdf.tag.td" value="full"/> *

* Normal data cells made of multiple elements are marked with *

* <property name="net.sf.jasperreports.export.pdf.tag.td" value="start"/> * on their first element and *

* <property name="net.sf.jasperreports.export.pdf.tag.td" value="end"/> * on their last element. *

* Just as in HTML tables, cells can span multiple rows and/or columns. Column span and * row span values for the current table cell can be specified using the following custom * properties on the same element where the cell start was marked (the element with the * full or start property marking the cell): *

* <property name="net.sf.jasperreports.export.pdf.tag.colspan" value="<number>"/> *

* <property name="net.sf.jasperreports.export.pdf.tag.rowspan" value="<number>"/> *

PDF Content Reading Order

* JasperReports uses the Z-order of the elements as present in the report template * (JRXML) to control reading order in the resulting PDF files. This is usually the intended * way for the documents to be read, so no specific modifications were required in order to * achieve it. * * @author Teodor Danciu ([email protected]) */ public class JRPdfExporterTagHelper implements StyledTextListWriter { @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_TABLE = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.table"; @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_TR = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.tr"; @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_TH = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.th"; @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_TD = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.td"; /** * @deprecated Replaced by styled text and HTML markup based bulleted and numbered lists. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_6_2_0 ) public static final String PROPERTY_TAG_L = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.l"; /** * @deprecated Replaced by styled text and HTML markup based bulleted and numbered lists. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_6_2_0 ) public static final String PROPERTY_TAG_LI = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.li"; /** * @deprecated Replaced by {@link AccessibilityUtil#PROPERTY_ACCESSIBILITY_TAG} and {@link AccessibilityTagEnum#H1}. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_H1 = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.h1"; /** * @deprecated Replaced by {@link AccessibilityUtil#PROPERTY_ACCESSIBILITY_TAG} and {@link AccessibilityTagEnum#H2}. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_H2 = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.h2"; /** * @deprecated Replaced by {@link AccessibilityUtil#PROPERTY_ACCESSIBILITY_TAG} and {@link AccessibilityTagEnum#H3}. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_H3 = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.h3"; /** * @deprecated Replaced by {@link AccessibilityUtil#PROPERTY_ACCESSIBILITY_TAG} and {@link AccessibilityTagEnum#H4}. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_6_2_0 ) public static final String PROPERTY_TAG_H4 = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.h4"; /** * @deprecated Replaced by {@link AccessibilityUtil#PROPERTY_ACCESSIBILITY_TAG} and {@link AccessibilityTagEnum#H5}. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_6_2_0 ) public static final String PROPERTY_TAG_H5 = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.h5"; /** * @deprecated Replaced by {@link AccessibilityUtil#PROPERTY_ACCESSIBILITY_TAG} and {@link AccessibilityTagEnum#H6}. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_6_2_0 ) public static final String PROPERTY_TAG_H6 = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.h6"; @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_COLSPAN = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.colspan"; @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.ELEMENT}, sinceVersion = PropertyConstants.VERSION_3_1_2 ) public static final String PROPERTY_TAG_ROWSPAN = JRPdfExporter.PDF_EXPORTER_PROPERTIES_PREFIX + "tag.rowspan"; public static final String TAG_START = "start"; public static final String TAG_END = "end"; public static final String TAG_FULL = "full"; protected JRPdfExporter exporter; protected PdfProducer pdfProducer; protected PdfStructure pdfStructure; protected PdfStructureEntry allTag; protected Stack tagStack; protected boolean isTagEmpty = true; protected int crtCrosstabRowY = -1; protected boolean insideCrosstabCellFrame; protected boolean isDataCellPrinted; protected boolean isTagged; protected String language; /** * */ protected JRPdfExporterTagHelper(JRPdfExporter exporter) { this.exporter = exporter; } /** * */ protected void setTagged(boolean isTagged) { this.isTagged = isTagged; } /** * */ protected void setLanguage(String language) { this.language = language; } /** * */ protected void setPdfProducer(PdfProducer pdfProducer) { this.pdfProducer = pdfProducer; this.pdfStructure = pdfProducer.getPdfStructure(); if (isTagged) { pdfProducer.setTagged(); } } /** * */ protected void init() { if (isTagged) { allTag = pdfStructure.createAllTag(language); tagStack = new Stack<>(); tagStack.push(allTag); } } protected void startPageAnchor() { if (isTagged) { pdfStructure.beginTag(allTag, "Anchor"); } } protected void endPageAnchor() { if (isTagged) { pdfStructure.endTag(); } } protected void startPage() { crtCrosstabRowY = -1; insideCrosstabCellFrame = false; isDataCellPrinted = false; } protected void endPage() { if (isTagged) { if (crtCrosstabRowY >= 0) //crosstab still open { //end the current row //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); //end the table //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); } } } protected void startElement(JRPrintElement element) { if (isTagged) { JRPrintFrame frame = element instanceof JRPrintFrame ? (JRPrintFrame) element : null; boolean isCellContentsFrame = frame != null && frame.getPropertiesMap().hasProperties() && frame.getPropertiesMap().getProperty(JRCellContents.PROPERTY_TYPE) != null; if (isCellContentsFrame) { insideCrosstabCellFrame = true; if (crtCrosstabRowY >= 0) //crosstab already started { if (JRCellContents.TYPE_DATA.equals(frame.getPropertiesMap().getProperty(JRCellContents.PROPERTY_TYPE))) { isDataCellPrinted = true; } if (crtCrosstabRowY != frame.getY()) { //this is the first cell on a new row //end the current row //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); if ( isDataCellPrinted && (JRCellContents.TYPE_CROSSTAB_HEADER.equals(frame.getPropertiesMap().getProperty(JRCellContents.PROPERTY_TYPE)) || JRCellContents.TYPE_COLUMN_HEADER.equals(frame.getPropertiesMap().getProperty(JRCellContents.PROPERTY_TYPE))) ) { //end the table //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); //start table createTableStartTag(); //start crosstab isDataCellPrinted = false; } //start the new row createTrStartTag(); //keep crosstab open, but mark new row position and frame depth crtCrosstabRowY = frame.getY(); } } else { //start table and first row createTableStartTag(); createTrStartTag(); //start crosstab crtCrosstabRowY = frame.getY(); isDataCellPrinted = false; } } else { if (crtCrosstabRowY >= 0) //crosstab already started { if (!insideCrosstabCellFrame) { //normal element outside crosstab //end the current row //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); //end the table //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); //end crosstab crtCrosstabRowY = -1; } } // else // { // //normal element outside crosstab // } } createStartTags(element); } } protected void endElement(JRPrintElement element) { if (isTagged) { JRPrintFrame frame = element instanceof JRPrintFrame ? (JRPrintFrame) element : null; boolean isCellContentsFrame = frame != null && frame.getPropertiesMap().hasProperties() && frame.getPropertiesMap().getProperty(JRCellContents.PROPERTY_TYPE) != null; if (isCellContentsFrame) { insideCrosstabCellFrame = false; } createEndTags(element); } } protected void startImage(JRPrintImage printImage) { if (isTagged) { PdfStructureEntry imageTag = pdfStructure.beginTag(allTag, "Image"); if (printImage.getHyperlinkTooltip() != null) { imageTag.putString("Alt", printImage.getHyperlinkTooltip()); } } } protected void endImage() { if (isTagged) { pdfStructure.endTag(); } } protected void startText(boolean isHyperlink) { if (isTagged) { // PdfStructureElement parentTag = tableCellTag == null ? (tableHeaderTag == null ? allTag : tableHeaderTag): tableCellTag; // PdfStructureElement textTag = new PdfStructureElement(parentTag, PdfName.TEXT); pdfStructure.beginTag(tagStack.peek(), isHyperlink ? "Link" : "Text"); } } protected void startText(String text, boolean isHyperlink) { if (isTagged) { pdfStructure.beginTag(tagStack.peek(), isHyperlink ? "Link" : "Text", text); } } protected void endText() { if (isTagged) { pdfStructure.endTag(); isTagEmpty = false; } } protected void createStartTags(JRPrintElement element) { if (element.hasProperties()) { String prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TABLE); if (TAG_START.equals(prop) || TAG_FULL.equals(prop)) { createTableStartTag(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TR); if (TAG_START.equals(prop) || TAG_FULL.equals(prop)) { createTrStartTag(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TH); if (TAG_START.equals(prop) || TAG_FULL.equals(prop)) { createThStartTag(element); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TD); if (TAG_START.equals(prop) || TAG_FULL.equals(prop)) { createTdStartTag(element); } prop = element.getPropertiesMap().getProperty(JRCellContents.PROPERTY_TYPE); if ( JRCellContents.TYPE_CROSSTAB_HEADER.equals(prop) || JRCellContents.TYPE_COLUMN_HEADER.equals(prop) || JRCellContents.TYPE_ROW_HEADER.equals(prop) ) { createThStartTag(element); } if (JRCellContents.TYPE_DATA.equals(prop)) { createTdStartTag(element); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_L); if (TAG_START.equals(prop) || TAG_FULL.equals(prop)) { createListStartTag(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_LI); if (TAG_START.equals(prop) || TAG_FULL.equals(prop)) { createListItemStartTag(element); } createStartHeadingTags(element, PROPERTY_TAG_H1, AccessibilityTagEnum.H1); createStartHeadingTags(element, PROPERTY_TAG_H2, AccessibilityTagEnum.H2); createStartHeadingTags(element, PROPERTY_TAG_H3, AccessibilityTagEnum.H3); createStartHeadingTags(element, PROPERTY_TAG_H4, AccessibilityTagEnum.H4); createStartHeadingTags(element, PROPERTY_TAG_H5, AccessibilityTagEnum.H5); createStartHeadingTags(element, PROPERTY_TAG_H6, AccessibilityTagEnum.H6); } } protected void createStartHeadingTags(JRPrintElement element, String pdfTagProp, AccessibilityTagEnum accessibilityTag) { String accessibilityTagPropValue = element.getPropertiesMap().getProperty(AccessibilityUtil.PROPERTY_ACCESSIBILITY_TAG); String pdfTagPropValue = element.getPropertiesMap().getProperty(pdfTagProp); if ( accessibilityTag.getName().equals(accessibilityTagPropValue) || TAG_START.equals(pdfTagPropValue) || TAG_FULL.equals(pdfTagPropValue) ) { PdfStructureEntry headingTag = pdfStructure.createTag(tagStack.peek(), accessibilityTag.name()); //pdfContentByte.beginMarkedContentSequence(headingTag); headingTag.putArray("K"); tagStack.push(headingTag); isTagEmpty = true; } } protected void createTableStartTag() { PdfStructureEntry tableTag = pdfStructure.createTag(allTag, "Table"); //pdfContentByte.beginMarkedContentSequence(tableTag); tableTag.putArray("K"); tagStack.push(tableTag); } protected void createTrStartTag() { PdfStructureEntry tableRowTag = pdfStructure.createTag(tagStack.peek(), "TR"); //pdfContentByte.beginMarkedContentSequence(tableRowTag); tableRowTag.putArray("K"); tagStack.push(tableRowTag); } protected void createThStartTag(JRPrintElement element) { PdfStructureEntry tableHeaderTag = pdfStructure.createTag(tagStack.peek(), "TH"); //pdfContentByte.beginMarkedContentSequence(tableHeaderTag); tableHeaderTag.putArray("K"); tagStack.push(tableHeaderTag); isTagEmpty = true; createSpanTags(element, tableHeaderTag); } protected void createTdStartTag(JRPrintElement element) { PdfStructureEntry tableCellTag = pdfStructure.createTag(tagStack.peek(), "TD"); //pdfContentByte.beginMarkedContentSequence(tableCellTag); tableCellTag.putArray("K"); tagStack.push(tableCellTag); isTagEmpty = true; createSpanTags(element, tableCellTag); } protected void createSpanTags(JRPrintElement element, PdfStructureEntry parentTag) { Integer colSpan = null; try { String colSpanProp = element.getPropertiesMap().getProperty(PROPERTY_TAG_COLSPAN); if (colSpanProp != null) { colSpan = Integer.valueOf(colSpanProp); } } catch (NumberFormatException e) {} if (colSpan == null) { try { String colSpanProp = element.getPropertiesMap().getProperty(JRCellContents.PROPERTY_COLUMN_SPAN); if (colSpanProp != null) { colSpan = Integer.valueOf(colSpanProp); } } catch (NumberFormatException ex) {} } Integer rowSpan = null; try { String rowSpanProp = element.getPropertiesMap().getProperty(PROPERTY_TAG_ROWSPAN); if (rowSpanProp != null) { rowSpan = Integer.valueOf(rowSpanProp); } } catch (NumberFormatException e) {} if (rowSpan == null) { try { String rowSpanProp = element.getPropertiesMap().getProperty(JRCellContents.PROPERTY_ROW_SPAN); if (rowSpanProp != null) { rowSpan = Integer.valueOf(rowSpanProp); } } catch (NumberFormatException ex) {} } if (colSpan != null && colSpan > 1 || rowSpan != null && rowSpan > 1) { parentTag.setSpan(colSpan == null ? 0 : colSpan, rowSpan == null ? 0 : rowSpan); } } protected void createListStartTag() { PdfStructureEntry listTag = pdfStructure.createTag(tagStack.peek(), "L"); //pdfContentByte.beginMarkedContentSequence(tableTag); listTag.putArray("K"); tagStack.push(listTag); } protected void createListItemStartTag(JRPrintElement element) { PdfStructureEntry listItemTag = pdfStructure.createTag(tagStack.peek(), "LI"); //pdfContentByte.beginMarkedContentSequence(tableHeaderTag); listItemTag.putArray("K"); tagStack.push(listItemTag); isTagEmpty = true; } protected void createEndTags(JRPrintElement element)// throws DocumentException, IOException, JRException { if (element.hasProperties()) { createEndHeadingTags(element, PROPERTY_TAG_H6, AccessibilityTagEnum.H6); createEndHeadingTags(element, PROPERTY_TAG_H5, AccessibilityTagEnum.H5); createEndHeadingTags(element, PROPERTY_TAG_H4, AccessibilityTagEnum.H4); createEndHeadingTags(element, PROPERTY_TAG_H3, AccessibilityTagEnum.H3); createEndHeadingTags(element, PROPERTY_TAG_H2, AccessibilityTagEnum.H2); createEndHeadingTags(element, PROPERTY_TAG_H1, AccessibilityTagEnum.H1); String prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_LI); if (TAG_END.equals(prop) || TAG_FULL.equals(prop)) { //pdfContentByte.endMarkedContentSequence(); if (isTagEmpty) { pdfStructure.beginTag(tagStack.peek(), "Span"); pdfStructure.endTag(); } tagStack.pop(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_L); if (TAG_END.equals(prop) || TAG_FULL.equals(prop)) { //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); } prop = element.getPropertiesMap().getProperty(JRCellContents.PROPERTY_TYPE); if ( prop != null && (JRCellContents.TYPE_CROSSTAB_HEADER.equals(prop) || JRCellContents.TYPE_COLUMN_HEADER.equals(prop) || JRCellContents.TYPE_ROW_HEADER.equals(prop) || JRCellContents.TYPE_DATA.equals(prop))) { //pdfContentByte.endMarkedContentSequence(); if (isTagEmpty) { pdfStructure.beginTag(tagStack.peek(), "Span"); pdfStructure.endTag(); } tagStack.pop(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TD); if (TAG_END.equals(prop) || TAG_FULL.equals(prop)) { //pdfContentByte.endMarkedContentSequence(); if (isTagEmpty) { pdfStructure.beginTag(tagStack.peek(), "Span"); pdfStructure.endTag(); } tagStack.pop(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TH); if (TAG_END.equals(prop) || TAG_FULL.equals(prop)) { //pdfContentByte.endMarkedContentSequence(); if (isTagEmpty) { pdfStructure.beginTag(tagStack.peek(), "Span"); pdfStructure.endTag(); } tagStack.pop(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TR); if (TAG_END.equals(prop) || TAG_FULL.equals(prop)) { //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); } prop = element.getPropertiesMap().getProperty(PROPERTY_TAG_TABLE); if (TAG_END.equals(prop) || TAG_FULL.equals(prop)) { //pdfContentByte.endMarkedContentSequence(); tagStack.pop(); } } // else // { // //check to see if this is the first element without tag properties after a table // if (tagStack.size() > 2) // check to see if we are at least inside a table row (table/tr) // { // PdfStructureElement tag = tagStack.peek(); // if ( // PdfName.TABLEROW.equals(tag.get(PdfName.S)) // && PdfName.TABLE.equals(tag.getParent().get(PdfName.S)) // ) // { // // take out both row and table tags // tagStack.pop(); // tagStack.pop(); // } // } // } } protected void createEndHeadingTags(JRPrintElement element, String pdfTagProp, AccessibilityTagEnum accessibilityTag) { String accessibilityTagPropValue = element.getPropertiesMap().getProperty(AccessibilityUtil.PROPERTY_ACCESSIBILITY_TAG); String pdfTagPropValue = element.getPropertiesMap().getProperty(pdfTagProp); if ( accessibilityTag.getName().equals(accessibilityTagPropValue) || TAG_END.equals(pdfTagPropValue) || TAG_FULL.equals(pdfTagPropValue) ) { //pdfContentByte.endMarkedContentSequence(); if (isTagEmpty) { pdfStructure.beginTag(tagStack.peek(), "Span"); pdfStructure.endTag(); } tagStack.pop(); } } @Override public void startUl() { createListStartTag(); } @Override public void endUl() { tagStack.pop(); } @Override public void startOl(String type, int cutStart) { createListStartTag(); } @Override public void endOl() { tagStack.pop(); } @Override public void startLi(boolean noBullet) { createListItemStartTag(null); } @Override public void endLi() { if (isTagEmpty) { pdfStructure.beginTag(tagStack.peek(), "Span"); pdfStructure.endTag(); } tagStack.pop(); } protected StyledTextListWriter getListWriter() { return isTagged ? this : null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy