aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2012-09-26 11:31:40 +0000
committerVincent Hennebert <vhennebert@apache.org>2012-09-26 11:31:40 +0000
commita1af0b2481adf1d4bdb1279972a9d4e51e381f6a (patch)
tree00f0840c0593e48cc1c49878a6e2a1a78e20a9e9 /src
parent182bbad662b45ecc15e2cc3d3de6cde7bdc77bea (diff)
downloadxmlgraphics-fop-a1af0b2481adf1d4bdb1279972a9d4e51e381f6a.tar.gz
xmlgraphics-fop-a1af0b2481adf1d4bdb1279972a9d4e51e381f6a.zip
Bugzilla #53902: Added possibility to define 'header' table columns (the same way as fo:table-header allows to define header rows).
When accessibility is enabled, this allows to set the appropriate Scope attribute on the corresponding TH cells. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1390412 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java33
-rw-r--r--src/java/org/apache/fop/fo/Constants.java5
-rw-r--r--src/java/org/apache/fop/fo/FOPropertyMapping.java6
-rw-r--r--src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java1
-rw-r--r--src/java/org/apache/fop/fo/extensions/InternalElementMapping.java3
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableColumn.java12
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java29
7 files changed, 71 insertions, 18 deletions
diff --git a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
index 93b815d30..09a814ef5 100644
--- a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
+++ b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
@@ -20,6 +20,7 @@
package org.apache.fop.accessibility.fo;
import java.util.Locale;
+import java.util.Stack;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
@@ -30,6 +31,7 @@ import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.fo.flow.AbstractGraphics;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.Block;
@@ -70,6 +72,10 @@ class StructureTreeEventTrigger extends FOEventHandler {
private LayoutMasterSet layoutMasterSet;
+ private final Stack<Table> tables = new Stack<Table>();
+
+ private final Stack<Boolean> inTableHeader = new Stack<Boolean>();
+
public StructureTreeEventTrigger(StructureTreeEventHandler structureTreeEventHandler) {
this.structureTreeEventHandler = structureTreeEventHandler;
}
@@ -195,42 +201,51 @@ class StructureTreeEventTrigger extends FOEventHandler {
@Override
public void startTable(Table tbl) {
+ tables.push(tbl);
startElement(tbl);
}
@Override
public void endTable(Table tbl) {
endElement(tbl);
+ tables.pop();
}
@Override
public void startHeader(TableHeader header) {
+ inTableHeader.push(Boolean.TRUE);
startElement(header);
}
@Override
public void endHeader(TableHeader header) {
endElement(header);
+ inTableHeader.pop();
}
@Override
public void startFooter(TableFooter footer) {
+ // TODO Shouldn't it be true?
+ inTableHeader.push(Boolean.FALSE);
startElement(footer);
}
@Override
public void endFooter(TableFooter footer) {
endElement(footer);
+ inTableHeader.pop();
}
@Override
public void startBody(TableBody body) {
+ inTableHeader.push(Boolean.FALSE);
startElement(body);
}
@Override
public void endBody(TableBody body) {
endElement(body);
+ inTableHeader.pop();
}
@Override
@@ -248,6 +263,24 @@ class StructureTreeEventTrigger extends FOEventHandler {
AttributesImpl attributes = new AttributesImpl();
addSpanAttribute(attributes, "number-columns-spanned", tc.getNumberColumnsSpanned());
addSpanAttribute(attributes, "number-rows-spanned", tc.getNumberRowsSpanned());
+ boolean rowHeader = inTableHeader.peek();
+ boolean columnHeader = tables.peek().getColumn(tc.getColumnNumber() - 1).isHeader();
+ if (rowHeader || columnHeader) {
+ final String th = "TH";
+ String role = tc.getCommonAccessibility().getRole();
+ /* Do not override a custom role */
+ if (role == null) {
+ role = th;
+ addNoNamespaceAttribute(attributes, "role", th);
+ }
+ if (role.equals(th)) {
+ if (columnHeader) {
+ String scope = rowHeader ? "Both" : "Row";
+ addAttribute(attributes, InternalElementMapping.URI, InternalElementMapping.SCOPE,
+ InternalElementMapping.STANDARD_PREFIX, scope);
+ }
+ }
+ }
startElement(tc, attributes);
}
diff --git a/src/java/org/apache/fop/fo/Constants.java b/src/java/org/apache/fop/fo/Constants.java
index 2d10dcdd9..6688042e2 100644
--- a/src/java/org/apache/fop/fo/Constants.java
+++ b/src/java/org/apache/fop/fo/Constants.java
@@ -785,8 +785,11 @@ public interface Constants {
*/
int PR_X_NUMBER_CONVERSION_FEATURES = 276;
+ /** Scope for table header */
+ int PR_X_HEADER_COLUMN = 277;
+
/** Number of property constants defined */
- int PROPERTY_COUNT = 276;
+ int PROPERTY_COUNT = 277;
// compound property constants
diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java
index d0d13fc17..a92b71ef9 100644
--- a/src/java/org/apache/fop/fo/FOPropertyMapping.java
+++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java
@@ -2513,6 +2513,12 @@ public final class FOPropertyMapping implements Constants {
m.setInherited(false);
m.setDefault("false");
addPropertyMaker("table-omit-header-at-break", m);
+
+ // fox:scope
+ m = new EnumProperty.Maker(PR_X_HEADER_COLUMN);
+ m.useGeneric(genericBoolean);
+ m.setDefault("false");
+ addPropertyMaker("fox:header", m);
}
private void createWritingModeProperties() {
diff --git a/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java b/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
index f0e03399f..a040edf1a 100644
--- a/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
+++ b/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
@@ -52,6 +52,7 @@ public class ExtensionElementMapping extends ElementMapping {
PROPERTY_ATTRIBUTES.add("disable-column-balancing");
//These are FOP's extension properties for accessibility
PROPERTY_ATTRIBUTES.add("alt-text");
+ PROPERTY_ATTRIBUTES.add("header");
}
/**
diff --git a/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java b/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java
index 687952d25..f257dd79d 100644
--- a/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java
+++ b/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java
@@ -43,12 +43,15 @@ public class InternalElementMapping extends ElementMapping {
/** The "struct-ref" attribute, to refer to a structure tree element. */
public static final String STRUCT_REF = "struct-ref";
+ public static final String SCOPE = "scope";
+
private static final Set<String> PROPERTY_ATTRIBUTES = new java.util.HashSet<String>();
static {
//These are FOP's extension properties for accessibility
PROPERTY_ATTRIBUTES.add(STRUCT_ID);
PROPERTY_ATTRIBUTES.add(STRUCT_REF);
+ PROPERTY_ATTRIBUTES.add(SCOPE);
}
/**
diff --git a/src/java/org/apache/fop/fo/flow/table/TableColumn.java b/src/java/org/apache/fop/fo/flow/table/TableColumn.java
index 5047822da..33cbff884 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableColumn.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableColumn.java
@@ -24,6 +24,7 @@ import org.xml.sax.Locator;
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Length;
+import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
@@ -44,6 +45,7 @@ public class TableColumn extends TableFObj {
private Length columnWidth;
private int numberColumnsRepeated;
private int numberColumnsSpanned;
+ private boolean isHeader;
// Unused but valid items, commented out for performance:
// private int visibility;
// End of property values
@@ -120,6 +122,7 @@ public class TableColumn extends TableFObj {
if (!this.implicitColumn) {
this.pList = pList;
}
+ isHeader = (pList.get(Constants.PR_X_HEADER_COLUMN).getEnum() == Constants.EN_TRUE);
}
/** {@inheritDoc} */
@@ -263,4 +266,13 @@ public class TableColumn extends TableFObj {
this.pList = null;
}
+ /**
+ * Returns {@code true} if this column is made of header cells.
+ *
+ * @return {@code true} if cells in this column are like TH cells in HTML
+ */
+ public boolean isHeader() {
+ return isHeader;
+ }
+
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
index 0d4a6b7fb..031224ffb 100644
--- a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
+++ b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
@@ -30,6 +30,7 @@ import org.apache.fop.accessibility.StructureTreeElement;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.pdf.PDFFactory;
import org.apache.fop.pdf.PDFParentTree;
@@ -138,7 +139,7 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
PDFStructElem structElem = createStructureElement(parent, structureType);
setAttributes(structElem, attributes);
addKidToParent(structElem, parent, attributes);
- registerStructureElement(structElem, pdfFactory);
+ registerStructureElement(structElem, pdfFactory, attributes);
return structElem;
}
@@ -155,7 +156,8 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
parent.addKid(kid);
}
- protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory) {
+ protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory,
+ Attributes attributes) {
pdfFactory.getDocument().registerStructureElement(structureElement);
}
@@ -240,22 +242,15 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
}
@Override
- protected PDFStructElem createStructureElement(StructureHierarchyMember parent,
- StructureType structureType) {
- PDFStructElem grandParent = ((PDFStructElem) parent).getParentStructElem();
- //TODO What to do with cells from table-footer? Currently they are mapped on TD.
- if (grandParent.getStructureType() == StandardStructureTypes.Table.THEAD) {
- structureType = StandardStructureTypes.Table.TH;
- } else {
- structureType = StandardStructureTypes.Table.TD;
- }
- return super.createStructureElement(parent, structureType);
- }
-
- @Override
- protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory) {
+ protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory,
+ Attributes attributes) {
if (structureElement.getStructureType() == Table.TH) {
- pdfFactory.getDocument().registerStructureElement(structureElement, Scope.COLUMN);
+ String scopeAttribute = attributes.getValue(InternalElementMapping.URI,
+ InternalElementMapping.SCOPE);
+ Scope scope = (scopeAttribute == null)
+ ? Scope.COLUMN
+ : Scope.valueOf(scopeAttribute.toUpperCase(Locale.ENGLISH));
+ pdfFactory.getDocument().registerStructureElement(structureElement, scope);
} else {
pdfFactory.getDocument().registerStructureElement(structureElement);
}