diff options
author | Peter Hancock <phancock@apache.org> | 2012-10-04 14:46:01 +0000 |
---|---|---|
committer | Peter Hancock <phancock@apache.org> | 2012-10-04 14:46:01 +0000 |
commit | af57408966c6e9a525475f52bdc96add31cb0e51 (patch) | |
tree | 7aec6fd97d2d6c501be6b2473aa399b236e37a51 /src/java/org/apache/fop/render/pdf | |
parent | 118f9d4f0f6aeed4971ea9cc61fd4d63198c9a84 (diff) | |
parent | d261730a4f7be752ae12a5ec52e6bad8ee4fa5c1 (diff) | |
download | xmlgraphics-fop-af57408966c6e9a525475f52bdc96add31cb0e51.tar.gz xmlgraphics-fop-af57408966c6e9a525475f52bdc96add31cb0e51.zip |
Merged trunk@1391502
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_RoundedCorners@1394098 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/render/pdf')
5 files changed, 394 insertions, 224 deletions
diff --git a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java b/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java deleted file mode 100644 index 68bfd8686..000000000 --- a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.pdf; - -import java.util.Map; - -import org.apache.fop.events.EventBroadcaster; -import org.apache.fop.pdf.PDFObject; -import org.apache.fop.pdf.PDFStructElem; -import org.apache.fop.pdf.StandardStructureTypes; -import org.apache.fop.pdf.StructureType; - -/** - * This class provides the standard mappings from Formatting Objects to PDF structure types. - */ -final class FOToPDFRoleMap { - - private static final Map<String, Mapper> DEFAULT_MAPPINGS = new java.util.HashMap<String, Mapper>(); - - static { - // Create the standard mappings - // Declarations and Pagination and Layout Formatting Objects - addMapping("root", StandardStructureTypes.Grouping.DOCUMENT); - addMapping("page-sequence", StandardStructureTypes.Grouping.PART); - addMapping("flow", StandardStructureTypes.Grouping.SECT); - addMapping("static-content", StandardStructureTypes.Grouping.SECT); - // Block-level Formatting Objects - addMapping("block", StandardStructureTypes.Paragraphlike.P); - addMapping("block-container", StandardStructureTypes.Grouping.DIV); - // Inline-level Formatting Objects - addMapping("character", StandardStructureTypes.InlineLevelStructure.SPAN); - addMapping("external-graphic", StandardStructureTypes.Illustration.FIGURE); - addMapping("instream-foreign-object", StandardStructureTypes.Illustration.FIGURE); - addMapping("inline", StandardStructureTypes.InlineLevelStructure.SPAN); - addMapping("inline-container", StandardStructureTypes.Grouping.DIV); - addMapping("page-number", StandardStructureTypes.InlineLevelStructure.QUOTE); - addMapping("page-number-citation", StandardStructureTypes.InlineLevelStructure.QUOTE); - addMapping("page-number-citation-last", StandardStructureTypes.InlineLevelStructure.QUOTE); - // Formatting Objects for Tables - addMapping("table-and-caption", StandardStructureTypes.Grouping.DIV); - addMapping("table", StandardStructureTypes.Table.TABLE); - addMapping("table-caption", StandardStructureTypes.Grouping.CAPTION); - addMapping("table-header", StandardStructureTypes.Table.THEAD); - addMapping("table-footer", StandardStructureTypes.Table.TFOOT); - addMapping("table-body", StandardStructureTypes.Table.TBODY); - addMapping("table-row", StandardStructureTypes.Table.TR); - addMapping("table-cell", new TableCellMapper()); - // Formatting Objects for Lists - addMapping("list-block", StandardStructureTypes.List.L); - addMapping("list-item", StandardStructureTypes.List.LI); - addMapping("list-item-body", StandardStructureTypes.List.LBODY); - addMapping("list-item-label", StandardStructureTypes.List.LBL); - // Dynamic Effects: Link and Multi Formatting Objects - addMapping("basic-link", StandardStructureTypes.InlineLevelStructure.LINK); - // Out-of-Line Formatting Objects - addMapping("float", StandardStructureTypes.Grouping.DIV); - addMapping("footnote", StandardStructureTypes.InlineLevelStructure.NOTE); - addMapping("footnote-body", StandardStructureTypes.Grouping.SECT); - addMapping("wrapper", StandardStructureTypes.InlineLevelStructure.SPAN); - addMapping("marker", StandardStructureTypes.Grouping.PRIVATE); - } - - private static void addMapping(String fo, StructureType structureType) { - addMapping(fo, new SimpleMapper(structureType)); - } - - private static void addMapping(String fo, Mapper mapper) { - DEFAULT_MAPPINGS.put(fo, mapper); - } - - - /** - * Maps a Formatting Object to a PDFName representing the associated structure type. - * @param fo the formatting object's local name - * @param role the value of the formatting object's role property - * @param parent the parent of the structure element to be mapped - * @param eventBroadcaster the event broadcaster - * @return the structure type or null if no match could be found - */ - public static StructureType mapFormattingObject(String fo, String role, - PDFObject parent, EventBroadcaster eventBroadcaster) { - StructureType type = null; - if (role == null) { - type = getDefaultMappingFor(fo, parent); - } else { - type = StandardStructureTypes.get(role); - if (type == null) { - type = getDefaultMappingFor(fo, parent); - PDFEventProducer.Provider.get(eventBroadcaster).nonStandardStructureType(fo, - fo, role, type.toString().substring(1)); - } - } - assert type != null; - return type; - } - - /** - * Maps a Formatting Object to a PDFName representing the associated structure type. - * @param fo the formatting object's local name - * @param parent the parent of the structure element to be mapped - * @return the structure type or NonStruct if no match could be found - */ - private static StructureType getDefaultMappingFor(String fo, PDFObject parent) { - Mapper mapper = DEFAULT_MAPPINGS.get(fo); - if (mapper != null) { - return mapper.getStructureType(parent); - } else { - return StandardStructureTypes.Grouping.NON_STRUCT; - } - } - - private interface Mapper { - StructureType getStructureType(PDFObject parent); - } - - private static class SimpleMapper implements Mapper { - - private StructureType structureType; - - public SimpleMapper(StructureType structureType) { - this.structureType = structureType; - } - - public StructureType getStructureType(PDFObject parent) { - return structureType; - } - - } - - private static class TableCellMapper implements Mapper { - - public StructureType getStructureType(PDFObject parent) { - 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) { - return StandardStructureTypes.Table.TH; - } else { - return StandardStructureTypes.Table.TD; - } - } - - } - - private FOToPDFRoleMap() { } -} diff --git a/src/java/org/apache/fop/render/pdf/PDFEventProducer.java b/src/java/org/apache/fop/render/pdf/PDFEventProducer.java index 40062f73f..4b8253867 100644 --- a/src/java/org/apache/fop/render/pdf/PDFEventProducer.java +++ b/src/java/org/apache/fop/render/pdf/PDFEventProducer.java @@ -59,12 +59,11 @@ public interface PDFEventProducer extends EventProducer { * Custom structure type is not standard as per the PDF reference. * * @param source the event source - * @param fo the local name of the formatting object having the custom type * @param type custom structure type * @param fallback default structure type used as a fallback * @event.severity WARN */ - void nonStandardStructureType(Object source, String fo, String type, String fallback); + void nonStandardStructureType(Object source, String type, String fallback); /** * The encryption length must be a multiple of 8 between 40 and 128. diff --git a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java index 1377bbfce..031224ffb 100644 --- a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java +++ b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java @@ -21,24 +21,266 @@ package org.apache.fop.render.pdf; import java.util.LinkedList; import java.util.Locale; +import java.util.Map; import org.xml.sax.Attributes; +import org.xml.sax.helpers.AttributesImpl; 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.PDFObject; import org.apache.fop.pdf.PDFParentTree; import org.apache.fop.pdf.PDFStructElem; import org.apache.fop.pdf.PDFStructTreeRoot; import org.apache.fop.pdf.StandardStructureAttributes.Table.Scope; +import org.apache.fop.pdf.StandardStructureTypes; +import org.apache.fop.pdf.StandardStructureTypes.Grouping; import org.apache.fop.pdf.StandardStructureTypes.Table; +import org.apache.fop.pdf.StructureHierarchyMember; import org.apache.fop.pdf.StructureType; +import org.apache.fop.util.XMLUtil; class PDFStructureTreeBuilder implements StructureTreeEventHandler { + private static final String ROLE = "role"; + + private static final Map<String, StructureElementBuilder> BUILDERS + = new java.util.HashMap<String, StructureElementBuilder>(); + + private static final StructureElementBuilder DEFAULT_BUILDER + = new DefaultStructureElementBuilder(Grouping.NON_STRUCT); + + static { + // Declarations and Pagination and Layout Formatting Objects + StructureElementBuilder regionBuilder = new RegionBuilder(); + addBuilder("root", StandardStructureTypes.Grouping.DOCUMENT); + addBuilder("page-sequence", new PageSequenceBuilder()); + addBuilder("static-content", regionBuilder); + addBuilder("flow", regionBuilder); + // Block-level Formatting Objects + addBuilder("block", StandardStructureTypes.Paragraphlike.P); + addBuilder("block-container", StandardStructureTypes.Grouping.DIV); + // Inline-level Formatting Objects + addBuilder("character", StandardStructureTypes.InlineLevelStructure.SPAN); + addBuilder("external-graphic", new ImageBuilder()); + addBuilder("instream-foreign-object", new ImageBuilder()); + addBuilder("inline", StandardStructureTypes.InlineLevelStructure.SPAN); + addBuilder("inline-container", StandardStructureTypes.Grouping.DIV); + addBuilder("page-number", StandardStructureTypes.InlineLevelStructure.QUOTE); + addBuilder("page-number-citation", StandardStructureTypes.InlineLevelStructure.QUOTE); + addBuilder("page-number-citation-last", StandardStructureTypes.InlineLevelStructure.QUOTE); + // Formatting Objects for Tables + addBuilder("table-and-caption", StandardStructureTypes.Grouping.DIV); + addBuilder("table", new TableBuilder()); + addBuilder("table-caption", StandardStructureTypes.Grouping.CAPTION); + addBuilder("table-header", StandardStructureTypes.Table.THEAD); + addBuilder("table-footer", new TableFooterBuilder()); + addBuilder("table-body", StandardStructureTypes.Table.TBODY); + addBuilder("table-row", StandardStructureTypes.Table.TR); + addBuilder("table-cell", new TableCellBuilder()); + // Formatting Objects for Lists + addBuilder("list-block", StandardStructureTypes.List.L); + addBuilder("list-item", StandardStructureTypes.List.LI); + addBuilder("list-item-body", StandardStructureTypes.List.LBODY); + addBuilder("list-item-label", StandardStructureTypes.List.LBL); + // Dynamic Effects: Link and Multi Formatting Objects + addBuilder("basic-link", StandardStructureTypes.InlineLevelStructure.LINK); + // Out-of-Line Formatting Objects + addBuilder("float", StandardStructureTypes.Grouping.DIV); + addBuilder("footnote", StandardStructureTypes.InlineLevelStructure.NOTE); + addBuilder("footnote-body", StandardStructureTypes.Grouping.SECT); + addBuilder("wrapper", StandardStructureTypes.InlineLevelStructure.SPAN); + addBuilder("marker", StandardStructureTypes.Grouping.PRIVATE); + + addBuilder("#PCDATA", new PlaceholderBuilder()); + } + + private static void addBuilder(String fo, StructureType structureType) { + addBuilder(fo, new DefaultStructureElementBuilder(structureType)); + } + + private static void addBuilder(String fo, StructureElementBuilder mapper) { + BUILDERS.put(fo, mapper); + } + + private interface StructureElementBuilder { + + PDFStructElem build(StructureHierarchyMember parent, Attributes attributes, PDFFactory pdfFactory, + EventBroadcaster eventBroadcaster); + + } + + private static class DefaultStructureElementBuilder implements StructureElementBuilder { + + private final StructureType defaultStructureType; + + DefaultStructureElementBuilder(StructureType structureType) { + this.defaultStructureType = structureType; + } + + public final PDFStructElem build(StructureHierarchyMember parent, Attributes attributes, + PDFFactory pdfFactory, EventBroadcaster eventBroadcaster) { + String role = attributes.getValue(ROLE); + StructureType structureType; + if (role == null) { + structureType = defaultStructureType; + } else { + structureType = StandardStructureTypes.get(role); + if (structureType == null) { + structureType = defaultStructureType; + PDFEventProducer.Provider.get(eventBroadcaster).nonStandardStructureType(role, role, + structureType.toString()); + } + } + PDFStructElem structElem = createStructureElement(parent, structureType); + setAttributes(structElem, attributes); + addKidToParent(structElem, parent, attributes); + registerStructureElement(structElem, pdfFactory, attributes); + return structElem; + } + + protected PDFStructElem createStructureElement(StructureHierarchyMember parent, + StructureType structureType) { + return new PDFStructElem(parent, structureType); + } + + protected void setAttributes(PDFStructElem structElem, Attributes attributes) { + } + + protected void addKidToParent(PDFStructElem kid, StructureHierarchyMember parent, + Attributes attributes) { + parent.addKid(kid); + } + + protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory, + Attributes attributes) { + pdfFactory.getDocument().registerStructureElement(structureElement); + } + + } + + private static class PageSequenceBuilder extends DefaultStructureElementBuilder { + + PageSequenceBuilder() { + super(StandardStructureTypes.Grouping.PART); + } + + @Override + protected PDFStructElem createStructureElement(StructureHierarchyMember parent, + StructureType structureType) { + return new PageSequenceStructElem(parent, structureType); + } + + } + + private static class RegionBuilder extends DefaultStructureElementBuilder { + + RegionBuilder() { + super(StandardStructureTypes.Grouping.SECT); + } + + @Override + protected void addKidToParent(PDFStructElem kid, StructureHierarchyMember parent, + Attributes attributes) { + String flowName = attributes.getValue(Flow.FLOW_NAME); + ((PageSequenceStructElem) parent).addContent(flowName, kid); + } + + } + + private static class ImageBuilder extends DefaultStructureElementBuilder { + + ImageBuilder() { + super(StandardStructureTypes.Illustration.FIGURE); + } + + @Override + protected void setAttributes(PDFStructElem structElem, Attributes attributes) { + String altTextNode = attributes.getValue(ExtensionElementMapping.URI, "alt-text"); + if (altTextNode == null) { + altTextNode = "No alternate text specified"; + } + structElem.put("Alt", altTextNode); + } + + } + + private static class TableBuilder extends DefaultStructureElementBuilder { + + TableBuilder() { + super(StandardStructureTypes.Table.TABLE); + } + + @Override + protected PDFStructElem createStructureElement(StructureHierarchyMember parent, + StructureType structureType) { + return new TableStructElem(parent, structureType); + } + } + + private static class TableFooterBuilder extends DefaultStructureElementBuilder { + + public TableFooterBuilder() { + super(StandardStructureTypes.Table.TFOOT); + } + + @Override + protected void addKidToParent(PDFStructElem kid, StructureHierarchyMember parent, + Attributes attributes) { + ((TableStructElem) parent).addTableFooter(kid); + } + } + + private static class TableCellBuilder extends DefaultStructureElementBuilder { + + TableCellBuilder() { + super(StandardStructureTypes.Table.TD); + } + + @Override + protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory, + Attributes attributes) { + if (structureElement.getStructureType() == Table.TH) { + 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); + } + } + + @Override + protected void setAttributes(PDFStructElem structElem, Attributes attributes) { + String columnSpan = attributes.getValue("number-columns-spanned"); + if (columnSpan != null) { + structElem.setTableAttributeColSpan(Integer.parseInt(columnSpan)); + } + String rowSpan = attributes.getValue("number-rows-spanned"); + if (rowSpan != null) { + structElem.setTableAttributeRowSpan(Integer.parseInt(rowSpan)); + } + } + + } + + private static class PlaceholderBuilder implements StructureElementBuilder { + + public PDFStructElem build(StructureHierarchyMember parent, Attributes attributes, + PDFFactory pdfFactory, EventBroadcaster eventBroadcaster) { + PDFStructElem elem = new PDFStructElem.Placeholder(parent); + parent.addKid(elem); + return elem; + } + + } + private PDFFactory pdfFactory; private EventBroadcaster eventBroadcaster; @@ -51,6 +293,10 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler { this.pdfFactory = pdfFactory; } + void setEventBroadcaster(EventBroadcaster eventBroadcaster) { + this.eventBroadcaster = eventBroadcaster; + } + void setLogicalStructureHandler(PDFLogicalStructureHandler logicalStructureHandler) { createRootStructureElement(logicalStructureHandler); } @@ -59,93 +305,53 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler { assert rootStructureElement == null; PDFParentTree parentTree = logicalStructureHandler.getParentTree(); PDFStructTreeRoot structTreeRoot = pdfFactory.getDocument().makeStructTreeRoot(parentTree); - rootStructureElement = createStructureElement("root", structTreeRoot, null); - structTreeRoot.addKid(rootStructureElement); + rootStructureElement = createStructureElement("root", structTreeRoot, + new AttributesImpl(), pdfFactory, eventBroadcaster); } - void setEventBroadcaster(EventBroadcaster eventBroadcaster) { - this.eventBroadcaster = eventBroadcaster; - } + private static PDFStructElem createStructureElement(String name, StructureHierarchyMember parent, + Attributes attributes, PDFFactory pdfFactory, EventBroadcaster eventBroadcaster) { + StructureElementBuilder builder = BUILDERS.get(name); + if (builder == null) { + // TODO is a fallback really necessary? + builder = DEFAULT_BUILDER; + } + return builder.build(parent, attributes, pdfFactory, eventBroadcaster); + } public void startPageSequence(Locale language, String role) { ancestors = new LinkedList<PDFStructElem>(); - PDFStructElem structElem = createStructureElement("page-sequence", rootStructureElement, role); + AttributesImpl attributes = new AttributesImpl(); + attributes.addAttribute("", ROLE, ROLE, XMLUtil.CDATA, role); + PDFStructElem structElem = createStructureElement("page-sequence", + rootStructureElement, attributes, pdfFactory, eventBroadcaster); if (language != null) { structElem.setLanguage(language); } - rootStructureElement.addKid(structElem); ancestors.add(structElem); } - private PDFStructElem createStructureElement(String name, PDFObject parent, String role) { - StructureType structureType = FOToPDFRoleMap.mapFormattingObject(name, role, parent, - eventBroadcaster); - if (structureType == Table.TH) { - return pdfFactory.getDocument().makeStructureElement(structureType, parent, Scope.COLUMN); - } else { - return pdfFactory.getDocument().makeStructureElement(structureType, parent); - } - } - public void endPageSequence() { } public StructureTreeElement startNode(String name, Attributes attributes) { PDFStructElem parent = ancestors.getFirst(); - String role = attributes.getValue("role"); - PDFStructElem structElem = createStructureElement(name, parent, role); - setSpanAttributes(structElem, attributes); - parent.addKid(structElem); + PDFStructElem structElem = createStructureElement(name, parent, attributes, + pdfFactory, eventBroadcaster); ancestors.addFirst(structElem); return structElem; } - private void setSpanAttributes(PDFStructElem structElem, Attributes attributes) { - String columnSpan = attributes.getValue("number-columns-spanned"); - if (columnSpan != null) { - structElem.setTableAttributeColSpan(Integer.parseInt(columnSpan)); - } - String rowSpan = attributes.getValue("number-rows-spanned"); - if (rowSpan != null) { - structElem.setTableAttributeRowSpan(Integer.parseInt(rowSpan)); - } - } - public void endNode(String name) { - removeFirstAncestor(); - } - - private void removeFirstAncestor() { ancestors.removeFirst(); } public StructureTreeElement startImageNode(String name, Attributes attributes) { - PDFStructElem parent = ancestors.getFirst(); - String role = attributes.getValue("role"); - PDFStructElem structElem = createStructureElement(name, parent, role); - parent.addKid(structElem); - String altTextNode = attributes.getValue(ExtensionElementMapping.URI, "alt-text"); - if (altTextNode != null) { - structElem.put("Alt", altTextNode); - } else { - structElem.put("Alt", "No alternate text specified"); - } - ancestors.addFirst(structElem); - return structElem; + return startNode(name, attributes); } public StructureTreeElement startReferencedNode(String name, Attributes attributes) { - PDFStructElem parent = ancestors.getFirst(); - String role = attributes.getValue("role"); - PDFStructElem structElem; - if ("#PCDATA".equals(name)) { - structElem = new PDFStructElem.Placeholder(parent); - } else { - structElem = createStructureElement(name, parent, role); - } - parent.addKid(structElem); - ancestors.addFirst(structElem); - return structElem; + return startNode(name, attributes); } } diff --git a/src/java/org/apache/fop/render/pdf/PageSequenceStructElem.java b/src/java/org/apache/fop/render/pdf/PageSequenceStructElem.java new file mode 100644 index 000000000..09d5b81a2 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/PageSequenceStructElem.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.pdf; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.fop.pdf.PDFArray; +import org.apache.fop.pdf.PDFObject; +import org.apache.fop.pdf.PDFStructElem; +import org.apache.fop.pdf.StructureType; + +class PageSequenceStructElem extends PDFStructElem { + + private List<PDFStructElem> regionBefores = new ArrayList<PDFStructElem>(); + + private List<PDFStructElem> regionAfters = new ArrayList<PDFStructElem>(); + + private List<PDFStructElem> regionStarts = new ArrayList<PDFStructElem>(); + + private List<PDFStructElem> regionEnds = new ArrayList<PDFStructElem>(); + + PageSequenceStructElem(PDFObject parent, StructureType structureType) { + super(parent, structureType); + } + + void addContent(String flowName, PDFStructElem content) { + if (flowName.equals("xsl-region-before")) { + regionBefores.add(content); + } else if (flowName.equals("xsl-region-after")) { + regionAfters.add(content); + } else if (flowName.equals("xsl-region-start")) { + regionStarts.add(content); + } else if (flowName.equals("xsl-region-end")) { + regionEnds.add(content); + } else { + addKid(content); + } + } + + @Override + protected boolean attachKids() { + assert !kids.isEmpty(); + PDFArray k = new PDFArray(); + addRegions(k, regionBefores); + addRegions(k, regionStarts); + addRegions(k, kids); + addRegions(k, regionEnds); + addRegions(k, regionAfters); + put("K", k); + return true; + } + + private void addRegions(PDFArray k, List<? extends PDFObject> regions) { + if (!regions.isEmpty()) { + for (PDFObject kid : regions) { + k.add(kid); + } + } + } + +} diff --git a/src/java/org/apache/fop/render/pdf/TableStructElem.java b/src/java/org/apache/fop/render/pdf/TableStructElem.java new file mode 100644 index 000000000..c44acb25c --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/TableStructElem.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.pdf; + +import org.apache.fop.pdf.PDFObject; +import org.apache.fop.pdf.PDFStructElem; +import org.apache.fop.pdf.StructureType; + +class TableStructElem extends PDFStructElem { + + private PDFStructElem tableFooter; + + public TableStructElem(PDFObject parent, StructureType structureType) { + super(parent, structureType); + } + + void addTableFooter(PDFStructElem footer) { + assert tableFooter == null; + tableFooter = footer; + } + + @Override + protected boolean attachKids() { + assert !kids.isEmpty(); + if (tableFooter != null) { + kids.add(tableFooter); + } + return super.attachKids(); + } + +} |