You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by vh...@apache.org on 2014/01/13 21:39:41 UTC
svn commit: r1557840 [5/9] - in
/xmlgraphics/fop/branches/Temp_InlineContainer: ./ examples/fo/basic/ lib/
src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/
src/documentation/intermediate-format-ng/ src/java/org/apache/fop/
src/java/org/apac...
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java Mon Jan 13 20:39:34 2014
@@ -27,6 +27,7 @@ import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.EnumMap;
+import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
@@ -55,24 +56,33 @@ import org.apache.fop.pdf.PDFFileSpec;
import org.apache.fop.pdf.PDFICCBasedColorSpace;
import org.apache.fop.pdf.PDFICCStream;
import org.apache.fop.pdf.PDFInfo;
+import org.apache.fop.pdf.PDFLayer;
import org.apache.fop.pdf.PDFMetadata;
import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFNames;
+import org.apache.fop.pdf.PDFNavigator;
+import org.apache.fop.pdf.PDFNull;
import org.apache.fop.pdf.PDFNumber;
import org.apache.fop.pdf.PDFOutputIntent;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFPageLabels;
import org.apache.fop.pdf.PDFReference;
+import org.apache.fop.pdf.PDFSetOCGStateAction;
import org.apache.fop.pdf.PDFText;
+import org.apache.fop.pdf.PDFTransitionAction;
import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.pdf.Version;
import org.apache.fop.pdf.VersionController;
+import org.apache.fop.render.pdf.extensions.PDFActionExtension;
+import org.apache.fop.render.pdf.extensions.PDFArrayExtension;
+import org.apache.fop.render.pdf.extensions.PDFCollectionEntryExtension;
import org.apache.fop.render.pdf.extensions.PDFDictionaryAttachment;
-import org.apache.fop.render.pdf.extensions.PDFDictionaryEntryExtension;
-import org.apache.fop.render.pdf.extensions.PDFDictionaryEntryType;
import org.apache.fop.render.pdf.extensions.PDFDictionaryExtension;
import org.apache.fop.render.pdf.extensions.PDFDictionaryType;
import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileAttachment;
+import org.apache.fop.render.pdf.extensions.PDFObjectType;
+import org.apache.fop.render.pdf.extensions.PDFPageExtension;
+import org.apache.fop.render.pdf.extensions.PDFReferenceExtension;
import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_PARAMS;
import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ACCESSCONTENT;
@@ -260,10 +270,189 @@ class PDFRenderingUtil {
public void renderDictionaryExtension(PDFDictionaryAttachment attachment, PDFPage currentPage) {
PDFDictionaryExtension extension = attachment.getExtension();
- if (extension.getDictionaryType() == PDFDictionaryType.Catalog) {
+ PDFDictionaryType type = extension.getDictionaryType();
+ if (type == PDFDictionaryType.Action) {
+ addNavigatorAction(extension);
+ } else if (type == PDFDictionaryType.Layer) {
+ addLayer(extension);
+ } else if (type == PDFDictionaryType.Navigator) {
+ addNavigator(extension);
+ } else {
+ renderDictionaryExtension(extension, currentPage);
+ }
+ }
+
+ public void addLayer(PDFDictionaryExtension extension) {
+ assert extension.getDictionaryType() == PDFDictionaryType.Layer;
+ String id = extension.getProperty(PDFDictionaryExtension.PROPERTY_ID);
+ if ((id != null) && (id.length() > 0)) {
+ PDFLayer layer = pdfDoc.getFactory().makeLayer(id);
+ layer.setResolver(new PDFLayer.Resolver(layer, extension) {
+ public void performResolution() {
+ PDFDictionaryExtension extension = (PDFDictionaryExtension) getExtension();
+ Object name = extension.findEntryValue("Name");
+ Object intent = extension.findEntryValue("Intent");
+ Object usage = makeDictionary(extension.findEntryValue("Usage"));
+ getLayer().populate(name, intent, usage);
+ }
+ });
+ }
+ }
+
+ public void addNavigatorAction(PDFDictionaryExtension extension) {
+ assert extension.getDictionaryType() == PDFDictionaryType.Action;
+ String id = extension.getProperty(PDFDictionaryExtension.PROPERTY_ID);
+ if ((id != null) && (id.length() > 0)) {
+ String type = extension.getProperty(PDFActionExtension.PROPERTY_TYPE);
+ if (type != null) {
+ if (type.equals("SetOCGState")) {
+ PDFSetOCGStateAction action = pdfDoc.getFactory().makeSetOCGStateAction(id);
+ action.setResolver(new PDFSetOCGStateAction.Resolver(action, extension) {
+ public void performResolution() {
+ PDFDictionaryExtension extension = (PDFDictionaryExtension) getExtension();
+ Object state = makeArray(extension.findEntryValue("State"));
+ Object preserveRB = extension.findEntryValue("PreserveRB");
+ Object nextAction = makeDictionaryOrArray(extension.findEntryValue("Next"));
+ getAction().populate(state, preserveRB, nextAction);
+ }
+ });
+ } else if (type.equals("Trans")) {
+ PDFTransitionAction action = pdfDoc.getFactory().makeTransitionAction(id);
+ action.setResolver(new PDFTransitionAction.Resolver(action, extension) {
+ public void performResolution() {
+ PDFDictionaryExtension extension = (PDFDictionaryExtension) getExtension();
+ Object transition = makeDictionary(extension.findEntryValue("Trans"));
+ Object nextAction = makeDictionaryOrArray(extension.findEntryValue("Next"));
+ getAction().populate(transition, nextAction);
+ }
+ });
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+ }
+
+ public void addNavigator(PDFDictionaryExtension extension) {
+ assert extension.getDictionaryType() == PDFDictionaryType.Navigator;
+ String id = extension.getProperty(PDFDictionaryExtension.PROPERTY_ID);
+ if ((id != null) && (id.length() > 0)) {
+ PDFNavigator navigator = pdfDoc.getFactory().makeNavigator(id);
+ navigator.setResolver(new PDFNavigator.Resolver(navigator, extension) {
+ public void performResolution() {
+ PDFDictionaryExtension extension = (PDFDictionaryExtension) getExtension();
+ Object nextAction = makeDictionary(extension.findEntryValue("NA"));
+ Object next = makeDictionary(extension.findEntryValue("Next"));
+ Object prevAction = makeDictionary(extension.findEntryValue("PA"));
+ Object prev = makeDictionary(extension.findEntryValue("Prev"));
+ Object duration = extension.findEntryValue("Dur");
+ getNavigator().populate(nextAction, next, prevAction, prev, duration);
+ }
+ });
+ }
+ }
+
+ private Object makeArray(Object value) {
+ if (value == null) {
+ return null;
+ } else if (value instanceof PDFReferenceExtension) {
+ return resolveReference((PDFReferenceExtension) value);
+ } else if (value instanceof List<?>) {
+ return populateArray(new PDFArray(), (List<?>) value);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private Object populateArray(PDFArray array, List<?> entries) {
+ for (PDFCollectionEntryExtension entry : (List<PDFCollectionEntryExtension>) entries) {
+ PDFObjectType type = entry.getType();
+ if (type == PDFObjectType.Array) {
+ array.add(makeArray(entry.getValue()));
+ } else if (type == PDFObjectType.Boolean) {
+ array.add(entry.getValueAsBoolean());
+ } else if (type == PDFObjectType.Dictionary) {
+ array.add(makeDictionary(entry.getValue()));
+ } else if (type == PDFObjectType.Name) {
+ array.add(new PDFName(entry.getValueAsString()));
+ } else if (type == PDFObjectType.Number) {
+ array.add(new PDFNumber(entry.getValueAsNumber()));
+ } else if (type == PDFObjectType.Reference) {
+ array.add(resolveReference((PDFReferenceExtension) entry));
+ } else if (type == PDFObjectType.String) {
+ array.add(entry.getValue());
+ }
+ }
+ return array;
+ }
+
+ private Object makeDictionary(Object value) {
+ if (value == null) {
+ return null;
+ } else if (value instanceof PDFReferenceExtension) {
+ return resolveReference((PDFReferenceExtension) value);
+ } else if (value instanceof List<?>) {
+ return populateDictionary(new PDFDictionary(), (List<?>) value);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private Object populateDictionary(PDFDictionary dictionary, List<?> entries) {
+ for (PDFCollectionEntryExtension entry : (List<PDFCollectionEntryExtension>) entries) {
+ PDFObjectType type = entry.getType();
+ String key = entry.getKey();
+ if (type == PDFObjectType.Array) {
+ dictionary.put(key, makeArray(entry.getValue()));
+ } else if (type == PDFObjectType.Boolean) {
+ dictionary.put(key, entry.getValueAsBoolean());
+ } else if (type == PDFObjectType.Dictionary) {
+ dictionary.put(key, makeDictionary(entry.getValue()));
+ } else if (type == PDFObjectType.Name) {
+ dictionary.put(key, new PDFName(entry.getValueAsString()));
+ } else if (type == PDFObjectType.Number) {
+ dictionary.put(key, new PDFNumber(entry.getValueAsNumber()));
+ } else if (type == PDFObjectType.Reference) {
+ dictionary.put(key, resolveReference((PDFReferenceExtension) entry));
+ } else if (type == PDFObjectType.String) {
+ dictionary.put(key, entry.getValue());
+ }
+ }
+ return dictionary;
+ }
+
+ private Object makeDictionaryOrArray(Object value) {
+ if (value == null) {
+ return null;
+ } else if (value instanceof PDFReferenceExtension) {
+ return resolveReference((PDFReferenceExtension) value);
+ } else if (value instanceof List<?>) {
+ if (hasKeyedEntry((List<?>) value)) {
+ return populateDictionary(new PDFDictionary(), (List<?>) value);
+ } else {
+ return populateArray(new PDFArray(), (List<?>) value);
+ }
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private boolean hasKeyedEntry(List<?> entries) {
+ for (PDFCollectionEntryExtension entry : (List<PDFCollectionEntryExtension>) entries) {
+ if (entry.getKey() != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void renderDictionaryExtension(PDFDictionaryExtension extension, PDFPage currentPage) {
+ PDFDictionaryType type = extension.getDictionaryType();
+ if (type == PDFDictionaryType.Catalog) {
augmentDictionary(pdfDoc.getRoot(), extension);
- } else if (extension.getDictionaryType() == PDFDictionaryType.Page) {
- if (extension.matchesPageNumber(currentPage.getPageIndex() + 1)) {
+ } else if (type == PDFDictionaryType.Page) {
+ assert extension instanceof PDFPageExtension;
+ if (((PDFPageExtension) extension).matchesPageNumber(currentPage.getPageIndex() + 1)) {
augmentDictionary(currentPage, extension);
}
} else {
@@ -272,9 +461,12 @@ class PDFRenderingUtil {
}
private PDFDictionary augmentDictionary(PDFDictionary dictionary, PDFDictionaryExtension extension) {
- for (PDFDictionaryEntryExtension entry : extension.getEntries()) {
+ for (PDFCollectionEntryExtension entry : extension.getEntries()) {
if (entry instanceof PDFDictionaryExtension) {
- dictionary.put(entry.getKey(), augmentDictionary(new PDFDictionary(dictionary), (PDFDictionaryExtension) entry));
+ dictionary.put(entry.getKey(),
+ augmentDictionary(new PDFDictionary(dictionary), (PDFDictionaryExtension) entry));
+ } else if (entry instanceof PDFArrayExtension) {
+ dictionary.put(entry.getKey(), augmentArray(new PDFArray(dictionary), (PDFArrayExtension) entry));
} else {
augmentDictionary(dictionary, entry);
}
@@ -282,22 +474,68 @@ class PDFRenderingUtil {
return dictionary;
}
- private void augmentDictionary(PDFDictionary dictionary, PDFDictionaryEntryExtension entry) {
- PDFDictionaryEntryType type = entry.getType();
+ private void augmentDictionary(PDFDictionary dictionary, PDFCollectionEntryExtension entry) {
+ PDFObjectType type = entry.getType();
String key = entry.getKey();
- if (type == PDFDictionaryEntryType.Boolean) {
+ if (type == PDFObjectType.Boolean) {
dictionary.put(key, entry.getValueAsBoolean());
- } else if (type == PDFDictionaryEntryType.Name) {
+ } else if (type == PDFObjectType.Name) {
dictionary.put(key, new PDFName(entry.getValueAsString()));
- } else if (type == PDFDictionaryEntryType.Number) {
+ } else if (type == PDFObjectType.Number) {
dictionary.put(key, new PDFNumber(entry.getValueAsNumber()));
- } else if (type == PDFDictionaryEntryType.String) {
+ } else if (type == PDFObjectType.Reference) {
+ assert entry instanceof PDFReferenceExtension;
+ dictionary.put(key, resolveReference((PDFReferenceExtension) entry));
+ } else if (type == PDFObjectType.String) {
dictionary.put(key, entry.getValueAsString());
} else {
throw new IllegalStateException();
}
}
+ private Object resolveReference(PDFReferenceExtension entry) {
+ PDFReference reference = (PDFReference) entry.getResolvedReference();
+ if (reference == null) {
+ reference = pdfDoc.resolveExtensionReference(entry.getReferenceId());
+ if (reference != null) {
+ entry.setResolvedReference(reference);
+ }
+ return reference;
+ }
+ return PDFNull.INSTANCE;
+ }
+
+ private PDFArray augmentArray(PDFArray array, PDFArrayExtension extension) {
+ for (PDFCollectionEntryExtension entry : extension.getEntries()) {
+ if (entry instanceof PDFDictionaryExtension) {
+ array.add(augmentDictionary(new PDFDictionary(array), (PDFDictionaryExtension) entry));
+ } else if (entry instanceof PDFArrayExtension) {
+ array.add(augmentArray(new PDFArray(array), (PDFArrayExtension) entry));
+ } else {
+ augmentArray(array, entry);
+ }
+ }
+ return array;
+ }
+
+ private void augmentArray(PDFArray array, PDFCollectionEntryExtension entry) {
+ PDFObjectType type = entry.getType();
+ if (type == PDFObjectType.Boolean) {
+ array.add(entry.getValueAsBoolean());
+ } else if (type == PDFObjectType.Name) {
+ array.add(new PDFName(entry.getValueAsString()));
+ } else if (type == PDFObjectType.Number) {
+ array.add(new PDFNumber(entry.getValueAsNumber()));
+ } else if (type == PDFObjectType.Reference) {
+ assert entry instanceof PDFReferenceExtension;
+ array.add(resolveReference((PDFReferenceExtension) entry));
+ } else if (type == PDFObjectType.String) {
+ array.add(entry.getValueAsString());
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
public PDFDocument setupPDFDocument(OutputStream out) throws IOException {
if (this.pdfDoc != null) {
throw new IllegalStateException("PDFDocument already set up");
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java Mon Jan 13 20:39:34 2014
@@ -358,6 +358,7 @@ class PDFStructureTreeBuilder implements
}
public StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent) {
+ assert parent == null || parent instanceof PDFStructElem;
PDFStructElem parentElem = parent == null ? ancestors.getFirst() : (PDFStructElem) parent;
PDFStructElem structElem = createStructureElement(name, parentElem, attributes,
pdfFactory, eventBroadcaster);
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryAttachment.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryAttachment.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryAttachment.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryAttachment.java Mon Jan 13 20:39:34 2014
@@ -43,14 +43,13 @@ public class PDFDictionaryAttachment ext
}
public void toSAX(ContentHandler handler) throws SAXException {
- PDFDictionaryType dictionaryType = extension.getDictionaryType();
int pageNumber = 0;
- if (dictionaryType == PDFDictionaryType.Page) {
+ if (extension instanceof PDFPageExtension) {
if (handler instanceof GenerationHelperContentHandler) {
Object context = ((GenerationHelperContentHandler) handler).getContentHandlerContext();
if (context instanceof IFContext) {
int pageIndex = ((IFContext) context).getPageIndex();
- if ((pageIndex >= 0) && extension.matchesPageNumber(pageIndex + 1)) {
+ if ((pageIndex >= 0) && ((PDFPageExtension) extension).matchesPageNumber(pageIndex + 1)) {
pageNumber = pageIndex + 1;
} else {
pageNumber = -1;
@@ -69,24 +68,40 @@ public class PDFDictionaryAttachment ext
String qn = PREFIX + ":" + ln;
attributes = extractIFAttributes(attributes, dictionary);
handler.startElement(CATEGORY, ln, qn, attributes);
- for (PDFDictionaryEntryExtension entry : dictionary.getEntries()) {
+ for (PDFCollectionEntryExtension entry : dictionary.getEntries()) {
toSAX(handler, entry);
}
handler.endElement(CATEGORY, ln, qn);
}
- private void toSAX(ContentHandler handler, PDFDictionaryEntryExtension entry) throws SAXException {
+ private void toSAX(ContentHandler handler, PDFArrayExtension array) throws SAXException {
+ AttributesImpl attributes = new AttributesImpl();
+ String ln = array.getElementName();
+ String qn = PREFIX + ":" + ln;
+ attributes = extractIFAttributes(attributes, array);
+ handler.startElement(CATEGORY, ln, qn, attributes);
+ for (PDFCollectionEntryExtension entry : array.getEntries()) {
+ toSAX(handler, entry);
+ }
+ handler.endElement(CATEGORY, ln, qn);
+ }
+
+ private void toSAX(ContentHandler handler, PDFCollectionEntryExtension entry) throws SAXException {
if (entry instanceof PDFDictionaryExtension) {
toSAX(handler, (PDFDictionaryExtension) entry);
+ } else if (entry instanceof PDFArrayExtension) {
+ toSAX(handler, (PDFArrayExtension) entry);
} else {
AttributesImpl attributes = new AttributesImpl();
String ln = entry.getElementName();
String qn = PREFIX + ":" + ln;
attributes = extractIFAttributes(attributes, entry);
handler.startElement(CATEGORY, ln, qn, attributes);
- char[] characters = entry.getValueAsXMLEscapedString().toCharArray();
- if (characters.length > 0) {
- handler.characters(characters, 0, characters.length);
+ if (!(entry instanceof PDFReferenceExtension)) {
+ char[] characters = entry.getValueAsXMLEscapedString().toCharArray();
+ if (characters.length > 0) {
+ handler.characters(characters, 0, characters.length);
+ }
}
handler.endElement(CATEGORY, ln, qn);
}
@@ -94,16 +109,27 @@ public class PDFDictionaryAttachment ext
private static AttributesImpl extractIFAttributes(AttributesImpl attributes, PDFDictionaryExtension dictionary) {
PDFDictionaryType type = dictionary.getDictionaryType();
- if (type == PDFDictionaryType.Catalog) {
- // no specific attriburtes
+ if (dictionary.usesIDAttribute()) {
+ String idName = PDFDictionaryElement.ATT_ID;
+ String id = dictionary.getProperty(PDFDictionaryExtension.PROPERTY_ID);
+ if (id != null) {
+ attributes.addAttribute(null, idName, idName, "ID", id);
+ }
+ }
+ if (type == PDFDictionaryType.Action) {
+ String actionTypeName = PDFActionElement.ATT_TYPE;
+ String actionType = dictionary.getProperty(PDFActionExtension.PROPERTY_TYPE);
+ if (actionType != null) {
+ attributes.addAttribute(null, actionTypeName, actionTypeName, "CDATA", actionType);
+ }
} else if (type == PDFDictionaryType.Page) {
- String pageNumbersName = PDFDictionaryExtension.PROPERTY_PAGE_NUMBERS;
+ String pageNumbersName = PDFPageExtension.PROPERTY_PAGE_NUMBERS;
String pageNumbers = dictionary.getProperty(pageNumbersName);
if (pageNumbers != null) {
attributes.addAttribute(null, pageNumbersName, pageNumbersName, "CDATA", pageNumbers);
}
} else if (type == PDFDictionaryType.Dictionary) {
- String keyName = PDFDictionaryEntryExtension.PROPERTY_KEY;
+ String keyName = PDFCollectionEntryElement.ATT_KEY;
String key = dictionary.getKey();
if (key != null) {
attributes.addAttribute(null, keyName, keyName, "CDATA", key);
@@ -112,12 +138,28 @@ public class PDFDictionaryAttachment ext
return attributes;
}
- private static AttributesImpl extractIFAttributes(AttributesImpl attributes, PDFDictionaryEntryExtension entry) {
- String keyName = PDFDictionaryEntryExtension.PROPERTY_KEY;
+ private static AttributesImpl extractIFAttributes(AttributesImpl attributes, PDFArrayExtension array) {
+ String keyName = PDFCollectionEntryExtension.PROPERTY_KEY;
+ String key = array.getKey();
+ if (key != null) {
+ attributes.addAttribute(null, keyName, keyName, "CDATA", key);
+ }
+ return attributes;
+ }
+
+ private static AttributesImpl extractIFAttributes(AttributesImpl attributes, PDFCollectionEntryExtension entry) {
+ String keyName = PDFCollectionEntryElement.ATT_KEY;
String key = entry.getKey();
if (key != null) {
attributes.addAttribute(null, keyName, keyName, "CDATA", key);
}
+ if (entry instanceof PDFReferenceExtension) {
+ String refid = ((PDFReferenceExtension) entry).getReferenceId();
+ if (refid != null) {
+ String refidName = PDFReferenceElement.ATT_REFID;
+ attributes.addAttribute(null, refidName, refidName, "IDREF", refid);
+ }
+ }
return attributes;
}
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java Mon Jan 13 20:39:34 2014
@@ -23,7 +23,6 @@ import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.extensions.ExtensionAttachment;
@@ -34,38 +33,54 @@ import org.apache.fop.fo.extensions.Exte
* Extension element for dictionaries: pdf:{catalog,page,dictionary}. The specific type
* of dictionary is established at construction type.
*/
-public class PDFDictionaryElement extends AbstractPDFDictionaryElement {
+public class PDFDictionaryElement extends PDFCollectionEntryElement {
- public static final String ATT_PAGE_NUMBERS = PDFDictionaryExtension.PROPERTY_PAGE_NUMBERS;
-
- private PDFDictionaryExtension extension;
+ public static final String ATT_ID = PDFDictionaryExtension.PROPERTY_ID;
/**
* Main constructor
* @param parent parent FO node
*/
PDFDictionaryElement(FONode parent, PDFDictionaryType type) {
- super(parent);
- this.extension = new PDFDictionaryExtension(type);
+ super(parent, PDFObjectType.Dictionary, createExtension(type));
+ }
+
+ private static PDFDictionaryExtension createExtension(PDFDictionaryType type) {
+ if (type == PDFDictionaryType.Action) {
+ return new PDFActionExtension();
+ } else if (type == PDFDictionaryType.Catalog) {
+ return new PDFCatalogExtension();
+ } else if (type == PDFDictionaryType.Layer) {
+ return new PDFLayerExtension();
+ } else if (type == PDFDictionaryType.Navigator) {
+ return new PDFNavigatorExtension();
+ } else if (type == PDFDictionaryType.Page) {
+ return new PDFPageExtension();
+ } else {
+ return new PDFDictionaryExtension(type);
+ }
}
- public PDFDictionaryExtension getExtension() {
- return extension;
+ public PDFDictionaryExtension getDictionaryExtension() {
+ assert getExtension() instanceof PDFDictionaryExtension;
+ return (PDFDictionaryExtension) getExtension();
}
@Override
public void processNode(String elementName, Locator locator, Attributes attlist, PropertyList propertyList) throws FOPException {
- if (extension.getDictionaryType() == PDFDictionaryType.Catalog) {
- // no specific properties
- } else if (extension.getDictionaryType() == PDFDictionaryType.Page) {
- String pageNumbers = attlist.getValue(ATT_PAGE_NUMBERS);
- if (pageNumbers != null) {
- extension.setProperty(ATT_PAGE_NUMBERS, pageNumbers);
+ PDFDictionaryExtension extension = getDictionaryExtension();
+ if (extension.usesIDAttribute()) {
+ String id = attlist.getValue(ATT_ID);
+ if (id != null) {
+ extension.setProperty(PDFDictionaryExtension.PROPERTY_ID, id);
}
- } else if (extension.getDictionaryType() == PDFDictionaryType.Dictionary) {
+ }
+ if (extension.getDictionaryType() == PDFDictionaryType.Dictionary) {
String key = attlist.getValue(ATT_KEY);
if (key == null) {
- missingPropertyError(ATT_KEY);
+ if (parent instanceof PDFDictionaryElement) {
+ missingPropertyError(ATT_KEY);
+ }
} else if (key.length() == 0) {
invalidPropertyValueError(ATT_KEY, key, null);
} else {
@@ -78,16 +93,18 @@ public class PDFDictionaryElement extend
public void startOfNode() throws FOPException {
super.startOfNode();
String localName = getLocalName();
- if (localName.equals("catalog")) {
- if (parent.getNameId() != Constants.FO_DECLARATIONS) {
- invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), "rule.childOfDeclarations");
- }
+ if (localName.equals("action")) {
+ // handled in PDFActionElement subclass
+ } else if (localName.equals("catalog")) {
+ // handled in PDFCatalogElement subclass
+ } else if (localName.equals("layer")) {
+ // handled in PDFLayerElement subclass
+ } else if (localName.equals("navigator")) {
+ // handled in PDFNavigattorElement subclass
} else if (localName.equals("page")) {
- if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
- invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), "rule.childOfSPM");
- }
+ // handled in PDFPageElement subclass
} else if (localName.equals("dictionary")) {
- if (!PDFDictionaryType.hasValueOfElementName(parent.getLocalName())) {
+ if (!PDFDictionaryType.hasValueOfElementName(parent.getLocalName()) && !PDFObjectType.Array.elementName().equals(parent.getLocalName())) {
invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), null);
}
} else {
@@ -97,14 +114,15 @@ public class PDFDictionaryElement extend
@Override
protected void addChildNode(FONode child) throws FOPException {
+ PDFDictionaryExtension extension = getDictionaryExtension();
if (child instanceof PDFDictionaryElement) {
- PDFDictionaryExtension extension = ((PDFDictionaryElement) child).getExtension();
- if (extension.getDictionaryType() == PDFDictionaryType.Dictionary) {
- this.extension.addEntry(extension);
- }
- } else if (child instanceof PDFDictionaryEntryElement) {
- PDFDictionaryEntryExtension extension = ((PDFDictionaryEntryElement) child).getExtension();
- this.extension.addEntry(extension);
+ PDFDictionaryExtension entry = ((PDFDictionaryElement) child).getDictionaryExtension();
+ if (entry.getDictionaryType() == PDFDictionaryType.Dictionary) {
+ extension.addEntry(entry);
+ }
+ } else if (child instanceof PDFCollectionEntryElement) {
+ PDFCollectionEntryExtension entry = ((PDFCollectionEntryElement) child).getExtension();
+ extension.addEntry(entry);
}
}
@@ -115,12 +133,13 @@ public class PDFDictionaryElement extend
@Override
public String getLocalName() {
+ PDFDictionaryExtension extension = getDictionaryExtension();
return extension.getDictionaryType().elementName();
}
@Override
protected ExtensionAttachment instantiateExtensionAttachment() {
- return new PDFDictionaryAttachment(extension);
+ return new PDFDictionaryAttachment(getDictionaryExtension());
}
}
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java Mon Jan 13 20:39:34 2014
@@ -24,24 +24,36 @@ import java.util.Map;
// CSOFF: LineLengthCheck
-public class PDFDictionaryExtension extends PDFDictionaryEntryExtension {
+public class PDFDictionaryExtension extends PDFCollectionExtension {
+ public static final String PROPERTY_ID = "id";
public static final String PROPERTY_PAGE_NUMBERS = "page-numbers";
private static final long serialVersionUID = -1L;
private PDFDictionaryType dictionaryType;
private Map<String, String> properties;
- private List<PDFDictionaryEntryExtension> entries;
+ private List<PDFCollectionEntryExtension> entries;
PDFDictionaryExtension() {
+ this(PDFDictionaryType.Dictionary);
}
PDFDictionaryExtension(PDFDictionaryType dictionaryType) {
- super(PDFDictionaryEntryType.Dictionary);
+ super(PDFObjectType.Dictionary);
this.dictionaryType = dictionaryType;
this.properties = new java.util.HashMap<String, String>();
- this.entries = new java.util.ArrayList<PDFDictionaryEntryExtension>();
+ this.entries = new java.util.ArrayList<PDFCollectionEntryExtension>();
+ }
+
+ @Override
+ public void setValue(Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getValue() {
+ return getEntries();
}
public PDFDictionaryType getDictionaryType() {
@@ -56,15 +68,40 @@ public class PDFDictionaryExtension exte
return properties.get(name);
}
- public void addEntry(PDFDictionaryEntryExtension entry) {
- entries.add(entry);
+ @Override
+ public void addEntry(PDFCollectionEntryExtension entry) {
+ if ((entry.getKey() == null) || (entry.getKey().length() == 0)) {
+ throw new IllegalArgumentException();
+ } else {
+ entries.add(entry);
+ }
}
- public List<PDFDictionaryEntryExtension> getEntries() {
+ public List<PDFCollectionEntryExtension> getEntries() {
return entries;
}
- public PDFDictionaryEntryExtension getLastEntry() {
+ public PDFCollectionEntryExtension findEntry(String key) {
+ for (PDFCollectionEntryExtension entry : entries) {
+ String entryKey = entry.getKey();
+ if ((entryKey != null) && entryKey.equals(key)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+
+ public Object findEntryValue(String key) {
+ for (PDFCollectionEntryExtension entry : entries) {
+ String entryKey = entry.getKey();
+ if ((entryKey != null) && entryKey.equals(key)) {
+ return entry.getValue();
+ }
+ }
+ return null;
+ }
+
+ public PDFCollectionEntryExtension getLastEntry() {
if (entries.size() > 0) {
return entries.get(entries.size() - 1);
} else {
@@ -72,48 +109,8 @@ public class PDFDictionaryExtension exte
}
}
- /**
- * Determine if page dictionary and page number matches.
- * @param pageNumber page number, where first page number is 1
- * @return true if this dictionary is a page dictionary and specified page number matches specified page-number property
- */
- public boolean matchesPageNumber(int pageNumber) {
- if (dictionaryType != PDFDictionaryType.Page) {
- return false;
- }
- String pageNumbers = getProperty(PROPERTY_PAGE_NUMBERS);
- if ((pageNumbers == null) || (pageNumbers.length() == 0)) {
- return false;
- } else if (pageNumbers.equals("*")) {
- return true;
- } else {
- for (String interval : pageNumbers.split("\\s*,\\s*")) {
- String[] components = interval.split("\\s*-\\s*");
- if (components.length < 1) {
- continue;
- } else {
- try {
- int start = Integer.parseInt(components[0]);
- int end = 0;
- if (components.length > 1) {
- if (!components[1].equals("LAST")) {
- end = Integer.parseInt(components[1]);
- }
- }
- if ((end == 0) && (pageNumber == start)) {
- return true;
- } else if ((end > start) && (pageNumber >= start) && (pageNumber < end)) {
- return true;
- } else {
- continue;
- }
- } catch (NumberFormatException e) {
- continue;
- }
- }
- }
- }
- return false;
+ public boolean usesIDAttribute() {
+ return dictionaryType.usesIDAttribute();
}
@Override
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java Mon Jan 13 20:39:34 2014
@@ -25,17 +25,28 @@ package org.apache.fop.render.pdf.extens
* Enumeration type for PDF dictionary extension elements.
*/
public enum PDFDictionaryType {
- Dictionary("dictionary"), // generic (nested) dictionary element
- Catalog("catalog"), // catalog dictionary element
- Page("page"); // page dictionary element
+ Action("action", true), // action dictionary element
+ Catalog("catalog"), // catalog dictionary element
+ Dictionary("dictionary"), // generic (nested) dictionary element
+ Layer("layer", true), // optional content group dictionary element
+ Navigator("navigator", true), // navigation node dictionary element
+ Page("page"); // page dictionary element
private String elementName;
- PDFDictionaryType(String elementName) {
+ private boolean usesIDAttribute;
+ PDFDictionaryType(String elementName, boolean usesIDAttribute) {
this.elementName = elementName;
+ this.usesIDAttribute = usesIDAttribute;
+ }
+ PDFDictionaryType(String elementName) {
+ this(elementName, false);
}
public String elementName() {
return elementName;
}
+ public boolean usesIDAttribute() {
+ return usesIDAttribute;
+ }
static PDFDictionaryType valueOfElementName(String elementName) {
for (PDFDictionaryType type : values()) {
if (type.elementName.equals(elementName)) {
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java Mon Jan 13 20:39:34 2014
@@ -41,17 +41,56 @@ public class PDFElementMapping extends E
protected void initialize() {
if (foObjs == null) {
foObjs = new java.util.HashMap<String, Maker>();
+ // pdf:action
+ foObjs.put(PDFDictionaryType.Action.elementName(), new PDFActionElementMaker());
+ // pdf:array
+ foObjs.put(PDFObjectType.Array.elementName(), new PDFArrayElementMaker());
+ // pdf:boolean
+ foObjs.put(PDFObjectType.Boolean.elementName(), new PDFCollectionEntryElementMaker(PDFObjectType.Boolean));
+ // pdf:catalog
+ foObjs.put(PDFDictionaryType.Catalog.elementName(), new PDFCatalogElementMaker());
+ // pdf:dictionary
+ foObjs.put(PDFDictionaryType.Dictionary.elementName(), new PDFDictionaryElementMaker());
// pdf:embedded-file
foObjs.put(PDFEmbeddedFileElement.ELEMENT, new PDFEmbeddedFileElementMaker());
- // pdf:{catalog,page} et al.
- for (PDFDictionaryType type : PDFDictionaryType.values()) {
- foObjs.put(type.elementName(), new PDFDictionaryElementMaker(type));
- }
- for (PDFDictionaryEntryType type : PDFDictionaryEntryType.values()) {
- if (type != PDFDictionaryEntryType.Dictionary) {
- foObjs.put(type.elementName(), new PDFDictionaryEntryElementMaker(type));
- }
- }
+ // pdf:name
+ foObjs.put(PDFObjectType.Name.elementName(), new PDFCollectionEntryElementMaker(PDFObjectType.Name));
+ // pdf:number
+ foObjs.put(PDFObjectType.Number.elementName(), new PDFCollectionEntryElementMaker(PDFObjectType.Number));
+ // pdf:navigator
+ foObjs.put(PDFDictionaryType.Navigator.elementName(), new PDFNavigatorElementMaker());
+ // pdf:layer
+ foObjs.put(PDFDictionaryType.Layer.elementName(), new PDFLayerElementMaker());
+ // pdf:page
+ foObjs.put(PDFDictionaryType.Page.elementName(), new PDFPageElementMaker());
+ // pdf:reference
+ foObjs.put(PDFObjectType.Reference.elementName(), new PDFReferenceElementMaker());
+ // pdf:string
+ foObjs.put(PDFObjectType.String.elementName(), new PDFCollectionEntryElementMaker(PDFObjectType.String));
+ }
+ }
+
+ static class PDFActionElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFActionElement(parent);
+ }
+ }
+
+ static class PDFArrayElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFArrayElement(parent);
+ }
+ }
+
+ static class PDFCatalogElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFCatalogElement(parent);
+ }
+ }
+
+ static class PDFDictionaryElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFDictionaryElement(parent, PDFDictionaryType.Dictionary);
}
}
@@ -61,23 +100,38 @@ public class PDFElementMapping extends E
}
}
- static class PDFDictionaryElementMaker extends ElementMapping.Maker {
- private PDFDictionaryType dictionaryType;
- PDFDictionaryElementMaker(PDFDictionaryType dictionaryType) {
- this.dictionaryType = dictionaryType;
+ static class PDFLayerElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFLayerElement(parent);
}
+ }
+
+ static class PDFNavigatorElementMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new PDFDictionaryElement(parent, dictionaryType);
+ return new PDFNavigatorElement(parent);
}
}
- static class PDFDictionaryEntryElementMaker extends ElementMapping.Maker {
- private PDFDictionaryEntryType entryType;
- PDFDictionaryEntryElementMaker(PDFDictionaryEntryType entryType) {
+ static class PDFPageElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFPageElement(parent);
+ }
+ }
+
+ static class PDFCollectionEntryElementMaker extends ElementMapping.Maker {
+ private PDFObjectType entryType;
+ PDFCollectionEntryElementMaker(PDFObjectType entryType) {
this.entryType = entryType;
}
public FONode make(FONode parent) {
- return new PDFDictionaryEntryElement(parent, entryType);
+ return new PDFCollectionEntryElement(parent, entryType);
}
}
+
+ static class PDFReferenceElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFReferenceElement(parent);
+ }
+ }
+
}
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java Mon Jan 13 20:39:34 2014
@@ -49,7 +49,7 @@ public class PDFExtensionHandler extends
private Attributes lastAttributes;
// PDFDictionaryAttachment related
- private Stack<PDFDictionaryExtension> dictionaries = new Stack<PDFDictionaryExtension>();
+ private Stack<PDFCollectionExtension> collections = new Stack<PDFCollectionExtension>();
private boolean captureContent;
private StringBuffer characters;
@@ -58,29 +58,78 @@ public class PDFExtensionHandler extends
if (PDFExtensionAttachment.CATEGORY.equals(uri)) {
if (localName.equals(PDFEmbeddedFileAttachment.ELEMENT)) {
lastAttributes = new AttributesImpl(attributes);
- } else if (PDFDictionaryType.hasValueOfElementName(localName)) {
- PDFDictionaryExtension dictionary = new PDFDictionaryExtension(PDFDictionaryType.valueOfElementName(localName));
- String key = attributes.getValue(PDFDictionaryEntryExtension.PROPERTY_KEY);
+ } else if (PDFDictionaryType.Action.elementName().equals(localName)) {
+ PDFActionExtension action = new PDFActionExtension();
+ String id = attributes.getValue(PDFDictionaryElement.ATT_ID);
+ if (id != null) {
+ action.setProperty(PDFDictionaryExtension.PROPERTY_ID, id);
+ }
+ String type = attributes.getValue(PDFActionElement.ATT_TYPE);
+ if (type != null) {
+ action.setProperty(PDFActionExtension.PROPERTY_TYPE, type);
+ }
+ collections.push(action);
+ } else if (PDFObjectType.Array.elementName().equals(localName)) {
+ PDFArrayExtension array = new PDFArrayExtension();
+ String key = attributes.getValue(PDFCollectionEntryElement.ATT_KEY);
+ if (key != null) {
+ array.setKey(key);
+ }
+ collections.push(array);
+ } else if (PDFDictionaryType.Catalog.elementName().equals(localName)) {
+ PDFCatalogExtension catalog = new PDFCatalogExtension();
+ collections.push(catalog);
+ } else if (PDFDictionaryType.Dictionary.elementName().equals(localName)) {
+ PDFDictionaryExtension dictionary = new PDFDictionaryExtension();
+ String key = attributes.getValue(PDFCollectionEntryElement.ATT_KEY);
if (key != null) {
dictionary.setKey(key);
}
- if (dictionary.getDictionaryType() == PDFDictionaryType.Page) {
- String pageNumbers = attributes.getValue(PDFDictionaryElement.ATT_PAGE_NUMBERS);
- if (pageNumbers != null) {
- dictionary.setProperty(PDFDictionaryElement.ATT_PAGE_NUMBERS, pageNumbers);
- }
+ collections.push(dictionary);
+ } else if (PDFDictionaryType.Layer.elementName().equals(localName)) {
+ PDFLayerExtension layer = new PDFLayerExtension();
+ String id = attributes.getValue(PDFDictionaryElement.ATT_ID);
+ if (id != null) {
+ layer.setProperty(PDFDictionaryExtension.PROPERTY_ID, id);
+ }
+ collections.push(layer);
+ } else if (PDFDictionaryType.Navigator.elementName().equals(localName)) {
+ PDFNavigatorExtension navigator = new PDFNavigatorExtension();
+ String id = attributes.getValue(PDFDictionaryElement.ATT_ID);
+ if (id != null) {
+ navigator.setProperty(PDFDictionaryExtension.PROPERTY_ID, id);
+ }
+ collections.push(navigator);
+ } else if (PDFDictionaryType.Page.elementName().equals(localName)) {
+ PDFPageExtension page = new PDFPageExtension();
+ String pageNumbers = attributes.getValue(PDFPageElement.ATT_PAGE_NUMBERS);
+ if (pageNumbers != null) {
+ page.setProperty(PDFPageExtension.PROPERTY_PAGE_NUMBERS, pageNumbers);
+ }
+ collections.push(page);
+ } else if (PDFObjectType.hasValueOfElementName(localName)) {
+ PDFCollectionEntryExtension entry;
+ if (PDFObjectType.Reference.elementName().equals(localName)) {
+ entry = new PDFReferenceExtension();
+ } else {
+ entry = new PDFCollectionEntryExtension(PDFObjectType.valueOfElementName(localName));
}
- dictionaries.push(dictionary);
- } else if (PDFDictionaryEntryType.hasValueOfElementName(localName)) {
- PDFDictionaryEntryExtension entry = new PDFDictionaryEntryExtension(PDFDictionaryEntryType.valueOfElementName(localName));
- String key = attributes.getValue(PDFDictionaryEntryElement.ATT_KEY);
+ String key = attributes.getValue(PDFCollectionEntryElement.ATT_KEY);
if (key != null) {
entry.setKey(key);
}
- if (!dictionaries.empty()) {
- PDFDictionaryExtension dictionary = dictionaries.peek();
- dictionary.addEntry(entry);
- captureContent = true;
+ if (entry instanceof PDFReferenceExtension) {
+ String refid = attributes.getValue(PDFReferenceElement.ATT_REFID);
+ if (refid != null) {
+ ((PDFReferenceExtension) entry).setReferenceId(refid);
+ }
+ }
+ if (!collections.empty()) {
+ PDFCollectionExtension collection = collections.peek();
+ collection.addEntry(entry);
+ if (!(entry instanceof PDFReferenceExtension)) {
+ captureContent = true;
+ }
}
} else {
throw new SAXException("Unhandled element " + localName + " in namespace: " + uri);
@@ -107,33 +156,48 @@ public class PDFExtensionHandler extends
String name = lastAttributes.getValue("name");
String src = lastAttributes.getValue("src");
String desc = lastAttributes.getValue("description");
+ this.lastAttributes = null;
this.returnedObject = new PDFEmbeddedFileAttachment(name, src, desc);
} else if (PDFDictionaryType.hasValueOfElementName(localName)) {
- if (!dictionaries.empty()) {
- PDFDictionaryExtension dictionary = dictionaries.pop();
- if ((dictionary.getDictionaryType() == PDFDictionaryType.Catalog) || (dictionary.getDictionaryType() == PDFDictionaryType.Page)) {
+ if (!collections.empty() && (collections.peek() instanceof PDFDictionaryExtension)) {
+ PDFDictionaryExtension dictionary = (PDFDictionaryExtension) collections.pop();
+ if (!collections.empty()) {
+ PDFCollectionExtension collectionOuter = collections.peek();
+ collectionOuter.addEntry(dictionary);
+ } else if (dictionary.getDictionaryType() != PDFDictionaryType.Dictionary) {
this.returnedObject = new PDFDictionaryAttachment(dictionary);
- } else if (!dictionaries.empty()) {
- PDFDictionaryExtension dictionaryOuter = dictionaries.peek();
- dictionaryOuter.addEntry(dictionary);
+ } else {
+ throw new SAXException(new IllegalStateException("generic dictionary not permitted at outer level"));
+ }
+ } else {
+ throw new SAXException(new IllegalStateException("collections stack is empty or not a dictionary"));
+ }
+ } else if (PDFObjectType.Array.elementName().equals(localName)) {
+ if (!collections.empty() && (collections.peek() instanceof PDFArrayExtension)) {
+ PDFArrayExtension array = (PDFArrayExtension) collections.pop();
+ if (!collections.empty()) {
+ PDFCollectionExtension collectionOuter = collections.peek();
+ collectionOuter.addEntry(array);
+ } else {
+ throw new SAXException(new IllegalStateException("array not permitted at outer level"));
}
} else {
- throw new SAXException(new IllegalStateException("no active dictionary"));
+ throw new SAXException(new IllegalStateException("collections stack is empty or not an array"));
}
- } else if (PDFDictionaryEntryType.hasValueOfElementName(localName)) {
- if (!dictionaries.empty()) {
- PDFDictionaryExtension dictionary = dictionaries.peek();
- PDFDictionaryEntryExtension entry = dictionary.getLastEntry();
+ } else if (PDFObjectType.hasValueOfElementName(localName)) {
+ if (!collections.empty()) {
+ PDFCollectionExtension collection = collections.peek();
+ PDFCollectionEntryExtension entry = collection.getLastEntry();
if (entry != null) {
if (characters != null) {
entry.setValue(characters.toString());
characters = null;
}
} else {
- throw new SAXException(new IllegalStateException("no active entry"));
+ throw new SAXException(new IllegalStateException("no current entry"));
}
} else {
- throw new SAXException(new IllegalStateException("no active dictionary"));
+ throw new SAXException(new IllegalStateException("entry not permitted at outer level"));
}
}
}
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSFontUtils.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSFontUtils.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSFontUtils.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSFontUtils.java Mon Jan 13 20:39:34 2014
@@ -175,6 +175,15 @@ public class PSFontUtils extends org.apa
if (!tracker.isResourceSupplied(WINANSI_ENCODING_RESOURCE)) {
//Only out Base 14 fonts still use that
+ for (Typeface tf : fonts.values()) {
+ if (tf instanceof LazyFont) {
+ tf = ((LazyFont)tf).getRealFont();
+ if (tf instanceof SingleByteFont
+ && ((SingleByteFont) tf).getEncoding().getName().equals("custom")) {
+ defineEncoding(gen, ((SingleByteFont) tf).getEncoding());
+ }
+ }
+ }
defineWinAnsiEncoding(gen);
}
gen.commentln("%FOPBeginFontReencode");
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java Mon Jan 13 20:39:34 2014
@@ -19,26 +19,50 @@
package org.apache.fop.render.ps;
+import java.awt.Color;
+import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.imageio.ImageIO;
import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.transcoder.SVGAbstractTranscoder;
+import org.apache.batik.transcoder.TranscoderException;
+import org.apache.batik.transcoder.TranscoderInput;
+import org.apache.batik.transcoder.TranscoderOutput;
+import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
-import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
+import org.apache.xmlgraphics.ps.ImageEncoder;
+import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.fop.image.loader.batik.BatikImageFlavors;
import org.apache.fop.image.loader.batik.BatikUtil;
import org.apache.fop.render.ImageHandler;
import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.ps.svg.PSSVGGraphics2D;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
@@ -47,6 +71,9 @@ import org.apache.fop.svg.SVGUserAgent;
*/
public class PSImageHandlerSVG implements ImageHandler {
+ private static final Color FALLBACK_COLOR = new Color(255, 33, 117);
+ private HashMap<String, String> gradientsFound = new HashMap<String, String>();
+
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
BatikImageFlavors.SVG_DOM
};
@@ -58,78 +85,262 @@ public class PSImageHandlerSVG implement
PSGenerator gen = psContext.getGenerator();
ImageXMLDOM imageSVG = (ImageXMLDOM)image;
- //Controls whether text painted by Batik is generated using text or path operations
- boolean strokeText = false;
- //TODO Configure text stroking
-
- SVGUserAgent ua
- = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
-
- PSGraphics2D graphics = new PSGraphics2D(strokeText, gen);
- graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
-
- BridgeContext ctx = new PSBridgeContext(ua,
- (strokeText ? null : psContext.getFontInfo()),
- context.getUserAgent().getImageManager(),
- context.getUserAgent().getImageSessionContext());
-
- //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine)
- //to it.
- Document clonedDoc = BatikUtil.cloneSVGDocument(imageSVG.getDocument());
+ if (shouldRaster(imageSVG)) {
+ InputStream is = renderSVGToInputStream(context, imageSVG);
- GraphicsNode root;
+ float x = (float) pos.getX() / 1000f;
+ float y = (float) pos.getY() / 1000f;
+ float w = (float) pos.getWidth() / 1000f;
+ float h = (float) pos.getHeight() / 1000f;
+ Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h);
+
+ MaskedImage mi = convertToRGB(ImageIO.read(is));
+ BufferedImage ri = mi.getImage();
+ ImageEncoder encoder = ImageEncodingHelper.createRenderedImageEncoder(ri);
+ Dimension imgDim = new Dimension(ri.getWidth(), ri.getHeight());
+ String imgDescription = ri.getClass().getName();
+ ImageEncodingHelper helper = new ImageEncodingHelper(ri);
+ ColorModel cm = helper.getEncodedColorModel();
+ PSImageUtils.writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen, ri, mi.getMaskColor());
+ } else {
+ //Controls whether text painted by Batik is generated using text or path operations
+ boolean strokeText = false;
+ //TODO Configure text stroking
+
+ SVGUserAgent ua
+ = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
+
+ PSSVGGraphics2D graphics = new PSSVGGraphics2D(strokeText, gen);
+ graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
+
+ BridgeContext ctx = new PSBridgeContext(ua,
+ (strokeText ? null : psContext.getFontInfo()),
+ context.getUserAgent().getImageManager(),
+ context.getUserAgent().getImageSessionContext());
+
+ //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine)
+ //to it.
+ Document clonedDoc = BatikUtil.cloneSVGDocument(imageSVG.getDocument());
+
+ GraphicsNode root;
+ try {
+ GVTBuilder builder = new GVTBuilder();
+ root = builder.build(ctx, clonedDoc);
+ } catch (Exception e) {
+ SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
+ context.getUserAgent().getEventBroadcaster());
+ eventProducer.svgNotBuilt(this, e, image.getInfo().getOriginalURI());
+ return;
+ }
+ // get the 'width' and 'height' attributes of the SVG document
+ float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
+ float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
+
+ float sx = pos.width / w;
+ float sy = pos.height / h;
+
+ ctx = null;
+
+ gen.commentln("%FOPBeginSVG");
+ gen.saveGraphicsState();
+ final boolean clip = false;
+ if (clip) {
+ /*
+ * Clip to the svg area.
+ * Note: To have the svg overlay (under) a text area then use
+ * an fo:block-container
+ */
+ gen.writeln("newpath");
+ gen.defineRect(pos.getMinX() / 1000f, pos.getMinY() / 1000f,
+ pos.width / 1000f, pos.height / 1000f);
+ gen.writeln("clip");
+ }
+
+ // transform so that the coordinates (0,0) is from the top left
+ // and positive is down and to the right. (0,0) is where the
+ // viewBox puts it.
+ gen.concatMatrix(sx, 0, 0, sy, pos.getMinX() / 1000f, pos.getMinY() / 1000f);
+
+ AffineTransform transform = new AffineTransform();
+ // scale to viewbox
+ transform.translate(pos.getMinX(), pos.getMinY());
+ gen.getCurrentState().concatMatrix(transform);
+ try {
+ root.paint(graphics);
+ } catch (Exception e) {
+ SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
+ context.getUserAgent().getEventBroadcaster());
+ eventProducer.svgRenderingError(this, e, image.getInfo().getOriginalURI());
+ }
+
+ gen.restoreGraphicsState();
+ gen.commentln("%FOPEndSVG");
+ }
+ }
+
+ private InputStream renderSVGToInputStream(RenderingContext context, ImageXMLDOM imageSVG) throws IOException {
+ PNGTranscoder png = new PNGTranscoder();
+ Float width = getDimension(imageSVG.getDocument(), "width") * 8;
+ png.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, width);
+ Float height = getDimension(imageSVG.getDocument(), "height") * 8;
+ png.addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, height);
+ TranscoderInput input = new TranscoderInput(imageSVG.getDocument());
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ TranscoderOutput output = new TranscoderOutput(os);
try {
- GVTBuilder builder = new GVTBuilder();
- root = builder.build(ctx, clonedDoc);
- } catch (Exception e) {
+ png.transcode(input, output);
+ } catch (TranscoderException ex) {
SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
context.getUserAgent().getEventBroadcaster());
- eventProducer.svgNotBuilt(this, e, image.getInfo().getOriginalURI());
- return;
+ eventProducer.svgRenderingError(this, ex, imageSVG.getInfo().getOriginalURI());
+ } finally {
+ os.flush();
+ os.close();
+ }
+ return new ByteArrayInputStream(os.toByteArray());
+ }
+
+ private MaskedImage convertToRGB(BufferedImage alphaImage) {
+ int[] red = new int[256];
+ int[] green = new int[256];
+ int[] blue = new int[256];
+ BufferedImage rgbImage = new BufferedImage(alphaImage.getWidth(),
+ alphaImage.getHeight(), BufferedImage.TYPE_INT_RGB);
+ //Count occurances of each colour in image
+ for (int cx = 0; cx < alphaImage.getWidth(); cx++) {
+ for (int cy = 0; cy < alphaImage.getHeight(); cy++) {
+ int pixelValue = alphaImage.getRGB(cx, cy);
+ Color pixelColor = new Color(pixelValue);
+ red[pixelColor.getRed()]++;
+ green[pixelColor.getGreen()]++;
+ blue[pixelColor.getBlue()]++;
+ }
+ }
+ //Find colour not in image
+ Color alphaSwap = null;
+ for (int i = 0; i < 256; i++) {
+ if (red[i] == 0) {
+ alphaSwap = new Color(i, 0, 0);
+ break;
+ } else if (green[i] == 0) {
+ alphaSwap = new Color(0, i, 0);
+ break;
+ } else if (blue[i] == 0) {
+ alphaSwap = new Color(0, 0, i);
+ break;
+ }
+ }
+ //Check if all variations are used in all three colours
+ if (alphaSwap == null) {
+ //Fallback colour is no unique colour channel can be found
+ alphaSwap = FALLBACK_COLOR;
+ }
+ //Replace alpha channel with the new mask colour
+ for (int cx = 0; cx < alphaImage.getWidth(); cx++) {
+ for (int cy = 0; cy < alphaImage.getHeight(); cy++) {
+ int pixelValue = alphaImage.getRGB(cx, cy);
+ if (pixelValue == 0) {
+ rgbImage.setRGB(cx, cy, alphaSwap.getRGB());
+ } else {
+ rgbImage.setRGB(cx, cy, alphaImage.getRGB(cx, cy));
+ }
+ }
+ }
+ return new MaskedImage(rgbImage, alphaSwap);
+ }
+
+ private static class MaskedImage {
+ private Color maskColor = new Color(0, 0, 0);
+ private BufferedImage image;
+
+ public MaskedImage(BufferedImage image, Color maskColor) {
+ this.image = image;
+ this.maskColor = maskColor;
+ }
+
+ public Color getMaskColor() {
+ return maskColor;
+ }
+
+ public BufferedImage getImage() {
+ return image;
+ }
+ }
+
+ private Float getDimension(Document document, String dimension) {
+ if (document.getFirstChild().getAttributes().getNamedItem(dimension) != null) {
+ String width = document.getFirstChild().getAttributes().getNamedItem(dimension).getNodeValue();
+ width = width.replaceAll("[^\\d.]", "");
+ return Float.parseFloat(width);
}
- // get the 'width' and 'height' attributes of the SVG document
- float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
- float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
-
- float sx = pos.width / w;
- float sy = pos.height / h;
-
- ctx = null;
-
- gen.commentln("%FOPBeginSVG");
- gen.saveGraphicsState();
- final boolean clip = false;
- if (clip) {
- /*
- * Clip to the svg area.
- * Note: To have the svg overlay (under) a text area then use
- * an fo:block-container
- */
- gen.writeln("newpath");
- gen.defineRect(pos.getMinX() / 1000f, pos.getMinY() / 1000f,
- pos.width / 1000f, pos.height / 1000f);
- gen.writeln("clip");
- }
-
- // transform so that the coordinates (0,0) is from the top left
- // and positive is down and to the right. (0,0) is where the
- // viewBox puts it.
- gen.concatMatrix(sx, 0, 0, sy, pos.getMinX() / 1000f, pos.getMinY() / 1000f);
-
- AffineTransform transform = new AffineTransform();
- // scale to viewbox
- transform.translate(pos.getMinX(), pos.getMinY());
- gen.getCurrentState().concatMatrix(transform);
+ return null;
+ }
+
+ private boolean shouldRaster(ImageXMLDOM image) {
+ //A list of objects on which to check opacity
try {
- root.paint(graphics);
- } catch (Exception e) {
- SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
- context.getUserAgent().getEventBroadcaster());
- eventProducer.svgRenderingError(this, e, image.getInfo().getOriginalURI());
+ List<String> gradMatches = new ArrayList<String>();
+ gradMatches.add("radialGradient");
+ gradMatches.add("linearGradient");
+ return recurseSVGElements(image.getDocument().getChildNodes(), gradMatches, false);
+ } finally {
+ gradientsFound.clear();
}
+ }
- gen.restoreGraphicsState();
- gen.commentln("%FOPEndSVG");
+ private boolean recurseSVGElements(NodeList childNodes, List<String> gradMatches, boolean isMatched) {
+ boolean opacityFound = false;
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node curNode = childNodes.item(i);
+ if (isMatched && curNode.getLocalName() != null && curNode.getLocalName().equals("stop")) {
+ if (curNode.getAttributes().getNamedItem("style") != null) {
+ String[] stylePairs = curNode.getAttributes().getNamedItem("style").getNodeValue()
+ .split(";");
+ for (int styleAtt = 0; styleAtt < stylePairs.length; styleAtt++) {
+ String[] style = stylePairs[styleAtt].split(":");
+ if (style[0].equalsIgnoreCase("stop-opacity")) {
+ if (Double.parseDouble(style[1]) < 1) {
+ return true;
+ }
+ }
+ }
+ }
+ if (curNode.getAttributes().getNamedItem("stop-opacity") != null) {
+ String opacityValue = curNode.getAttributes().getNamedItem("stop-opacity").getNodeValue();
+ if (Double.parseDouble(opacityValue) < 1) {
+ return true;
+ }
+ }
+ }
+ String nodeName = curNode.getLocalName();
+ //Special case where rasterization needed for radial gradients
+ if (nodeName != null && nodeName.equals("ellipse")) {
+ String found = "";
+ String ellipseFill = curNode.getAttributes().getNamedItem("fill").getNodeValue();
+ Pattern pattern = Pattern.compile("#(.*?)\\)");
+ Matcher matcher = pattern.matcher(ellipseFill);
+ if (matcher.find()) {
+ found = matcher.group(1);
+ }
+ if (gradientsFound.get(found) != null) {
+ return true;
+ }
+ }
+ boolean inMatch = false;
+ if (!isMatched) {
+ inMatch = nodeName != null && gradMatches.contains(nodeName);
+ if (inMatch) {
+ gradientsFound.put(curNode.getAttributes().getNamedItem("id").getNodeValue(), nodeName);
+ }
+ } else {
+ inMatch = true;
+ }
+ opacityFound = recurseSVGElements(curNode.getChildNodes(), gradMatches, inMatch);
+ if (opacityFound) {
+ return true;
+ }
+ }
+ return opacityFound;
}
/** {@inheritDoc} */
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSPainter.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/ps/PSPainter.java Mon Jan 13 20:39:34 2014
@@ -116,7 +116,7 @@ public class PSPainter extends AbstractI
}
/** {@inheritDoc} */
- public void startGroup(AffineTransform transform) throws IFException {
+ public void startGroup(AffineTransform transform, String layer) throws IFException {
try {
PSGenerator generator = getGenerator();
saveGraphicsState();
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/RTFHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/RTFHandler.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/RTFHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/RTFHandler.java Mon Jan 13 20:39:34 2014
@@ -157,6 +157,7 @@ public class RTFHandler extends FOEventH
private PercentContext percentManager = new PercentContext();
+
/**
* Creates a new RTF structure handler.
* @param userAgent the FOUserAgent for this process
@@ -270,7 +271,7 @@ public class RTFHandler extends FOEventH
return;
} else {
- builderContext.popContainer();
+ builderContext.popContainer(RtfSection.class, this);
this.pagemaster = null;
}
}
@@ -377,10 +378,10 @@ public class RTFHandler extends FOEventH
//just do nothing
} else if (regionBefore != null
&& fl.getFlowName().equals(regionBefore.getRegionName())) {
- builderContext.popContainer();
+ builderContext.popContainer(RtfBefore.class, this);
} else if (regionAfter != null
&& fl.getFlowName().equals(regionAfter.getRegionName())) {
- builderContext.popContainer();
+ builderContext.popContainer(RtfAfter.class, this);
}
} catch (Exception e) {
log.error("endFlow: " + e.getMessage());
@@ -571,7 +572,7 @@ public class RTFHandler extends FOEventH
nestedTableDepth--;
builderContext.popTableContext();
- builderContext.popContainer();
+ builderContext.popContainer(RtfTable.class, this);
}
/** {@inheritDoc} */
@@ -605,21 +606,25 @@ public class RTFHandler extends FOEventH
/** {@inheritDoc} */
public void startHeader(TableHeader header) {
+ builderContext.pushPart(header);
startPart(header);
}
/** {@inheritDoc} */
public void endHeader(TableHeader header) {
+ builderContext.popPart(header.getClass(), this);
endPart(header);
}
/** {@inheritDoc} */
public void startFooter(TableFooter footer) {
+ builderContext.pushPart(footer);
startPart(footer);
}
/** {@inheritDoc} */
public void endFooter(TableFooter footer) {
+ builderContext.popPart(footer.getClass(), this);
endPart(footer);
}
@@ -711,11 +716,13 @@ public class RTFHandler extends FOEventH
* {@inheritDoc}
*/
public void startBody(TableBody body) {
+ builderContext.pushPart(body);
startPart(body);
}
/** {@inheritDoc} */
public void endBody(TableBody body) {
+ builderContext.popPart(TableBody.class, this);
endPart(body);
}
@@ -784,7 +791,7 @@ public class RTFHandler extends FOEventH
}
- builderContext.popContainer();
+ builderContext.popContainer(RtfTableRow.class, this);
builderContext.getTableContext().decreaseRowSpannings();
}
@@ -893,7 +900,7 @@ public class RTFHandler extends FOEventH
throw new RuntimeException(e.getMessage());
}
- builderContext.popContainer();
+ builderContext.popContainer(RtfTableCell.class, this);
builderContext.getTableContext().selectNextColumn();
}
@@ -929,7 +936,7 @@ public class RTFHandler extends FOEventH
return;
}
- builderContext.popContainer();
+ builderContext.popContainer(RtfList.class, this);
}
/** {@inheritDoc} */
@@ -976,7 +983,7 @@ public class RTFHandler extends FOEventH
return;
}
- builderContext.popContainer();
+ builderContext.popContainer(RtfListItem.class, this);
}
/** {@inheritDoc} */
@@ -1005,7 +1012,7 @@ public class RTFHandler extends FOEventH
return;
}
- builderContext.popContainer();
+ builderContext.popContainer(RtfListItemLabel.class, this);
}
/** {@inheritDoc} */
@@ -1070,7 +1077,7 @@ public class RTFHandler extends FOEventH
return;
}
- builderContext.popContainer();
+ builderContext.popContainer(RtfHyperLink.class, this);
}
/** {@inheritDoc} */
@@ -1306,7 +1313,7 @@ public class RTFHandler extends FOEventH
return;
}
- builderContext.popContainer();
+ builderContext.popContainer(RtfFootnote.class, this);
}
/** {@inheritDoc} */
@@ -1688,6 +1695,19 @@ public class RTFHandler extends FOEventH
}
/**
+ * Closes any mismatched tags that are detected in the RTF structure.
+ * @param containerClass The class representing the tag to close.
+ * @return Determines whether the tag mismatch has been handled.
+ */
+ public boolean endContainer(Class containerClass) {
+ if (containerClass == RtfTableRow.class) {
+ endRow(null);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Calls the event handlers for the passed FONode and all its elements.
*
* @param foNode FONode object which shall be recursed
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/rtflib/tools/BuilderContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/rtflib/tools/BuilderContext.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/rtflib/tools/BuilderContext.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/rtf/rtflib/tools/BuilderContext.java Mon Jan 13 20:39:34 2014
@@ -21,6 +21,12 @@ package org.apache.fop.render.rtf.rtflib
import java.util.Stack;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.render.rtf.RTFHandler;
+import org.apache.fop.render.rtf.RTFPlaceHolderHelper;
import org.apache.fop.render.rtf.rtflib.exceptions.RtfException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfOptions;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfContainer;
@@ -38,6 +44,10 @@ import org.apache.fop.render.rtf.rtflib.
*/
public class BuilderContext {
+
+ /** Static logging instance */
+ protected static final Log LOG = LogFactory.getLog(BuilderContext.class.getName());
+
/** stack of RtfContainers */
private final Stack containers = new Stack();
@@ -96,17 +106,22 @@ public class BuilderContext {
* @throws RtfException if not caught
*/
public RtfContainer getContainer(Class containerClass, boolean required,
- Object /*IBuilder*/ forWhichBuilder) throws RtfException {
+ Object forWhichBuilder) throws RtfException {
// TODO what to do if the desired container is not at the top of the stack?
// close top-of-stack container?
- final RtfContainer result = (RtfContainer)getObjectFromStack(containers,
+ RtfContainer result = (RtfContainer)getObjectFromStack(containers,
containerClass);
if (result == null && required) {
- throw new RtfException(
- "No RtfContainer of class '" + containerClass.getName()
- + "' available for '" + forWhichBuilder.getClass().getName() + "' builder"
- );
+ RTFPlaceHolderHelper placeHolderHelper = new RTFPlaceHolderHelper(this);
+ placeHolderHelper.createRTFPlaceholder(containerClass);
+ result = getContainer(containerClass, required, forWhichBuilder);
+ if (result == null) {
+ throw new RtfException(
+ "No RtfContainer of class '" + containerClass.getName()
+ + "' available for '" + forWhichBuilder.getClass().getName() + "' builder"
+ );
+ }
}
return result;
@@ -121,6 +136,14 @@ public class BuilderContext {
}
/**
+ * Push a Class representing a non-writeable section of the FO tree
+ * @param part the part
+ */
+ public void pushPart(FObj part) {
+ containers.push(part);
+ }
+
+ /**
* In some cases an RtfContainer must be replaced by another one on the
* stack. This happens when handling nested fo:blocks for example: after
* handling a nested block the enclosing block must switch to a new
@@ -142,8 +165,40 @@ public class BuilderContext {
}
/** pop the topmost RtfContainer from our stack */
- public void popContainer() {
- containers.pop();
+ public void popContainer(Class containerClass, RTFHandler handler) {
+ handlePop(containerClass, handler);
+ }
+
+ /** pop the topmost part class from our stack */
+ public void popPart(Class part, RTFHandler handler) {
+ handlePop(part, handler);
+ }
+
+ /**
+ * This method checks for any tag mismatches between what is being closed
+ * and what exists on the stack. If a mismatch is found, then it will push
+ * the object back onto the stack and attempt to close the given section
+ * before retrying with the current pop task.
+ * @param aClass The class to be popped from the stack
+ * @param handler The RTF handler class to fix any mismatches
+ */
+ private void handlePop(Class aClass, RTFHandler handler) {
+ Object object = containers.pop();
+ if (object.getClass() != aClass) {
+ pushAndClose(aClass, object, handler);
+ }
+ }
+
+ private void pushAndClose(Class aClass, Object object, RTFHandler handler) {
+ containers.push(object);
+ if (handler.endContainer(object.getClass())) {
+ popContainer(aClass, handler);
+ } else {
+ /* This should never happen unless a placeholder is not catered for
+ * in the RTFHandler.endContainer method. */
+ LOG.warn("Unhandled RTF structure tag mismatch detected between "
+ + aClass.getSimpleName() + " and " + object.getClass().getSimpleName());
+ }
}
/* push an IBuilder to our stack /
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/txt/TXTRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/txt/TXTRenderer.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/txt/TXTRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/txt/TXTRenderer.java Mon Jan 13 20:39:34 2014
@@ -583,6 +583,14 @@ public class TXTRenderer extends Abstrac
}
/** {@inheritDoc} */
+ protected void startLayer(String layer) {
+ }
+
+ /** {@inheritDoc} */
+ protected void endLayer() {
+ }
+
+ /** {@inheritDoc} */
protected void concatenateTransformationMatrix(AffineTransform at) {
currentState.push(new CTM(UnitConv.ptToMpt(at)));
}
Modified: xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/xml/XMLRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/xml/XMLRenderer.java?rev=1557840&r1=1557839&r2=1557840&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/xml/XMLRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_InlineContainer/src/java/org/apache/fop/render/xml/XMLRenderer.java Mon Jan 13 20:39:34 2014
@@ -545,6 +545,16 @@ public class XMLRenderer extends Abstrac
//only necessary for graphical output
}
+ /** {@inheritDoc} */
+ protected void startLayer(String layer) {
+ //only necessary for graphical output
+ }
+
+ /** {@inheritDoc} */
+ protected void endLayer() {
+ //only necessary for graphical output
+ }
+
/**
* {@inheritDoc}
* org.apache.fop.area.inline.InlineArea)
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org