Extension Elements that provide ExtensionAttachments are not added as such to the child element list of a formatting object since they work a little differently and should free memory as soon as possible. The PostScript extension described in http://wiki.apache.org/xmlgraphics-fop/ExtensionsForPostScript are now fully implemented but under the namespace URI "http://xmlgraphics.apache.org/fop/postscript", not "http://xml.apache.org/fop/extensions". I'll need to look at namespaces again separately, later. The new PSExtensionElementMapping is currently hard-coded into FOTreeBuilder as are the other ElementMapping classes. OffDocumentItem is now an interface, AbstractOffDocumentItem now providing the base functionality of the former OffDocumentItem class. Lots of clean-up and javadocs while working through this, for example: FObj.childNodes is not public anymore. Instead a special method on fo.flow.InstreamForeignObject provides the child in the one case childNodes was directly accessed. PropertyMaker access in FObj is also done through a method now, propertyListTable is now private. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@267209 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_90-alpha1
@@ -0,0 +1,70 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.area; | |||
/** | |||
* Abstract base class for objects that are processed by the renderer outside | |||
* of the actual document. | |||
* This object can be handled by the renderer according to these | |||
* possibilities: IMMEDIATELY, AFTER_PAGE, START_OF_DOC or END_OF_DOC. | |||
*/ | |||
public abstract class AbstractOffDocumentItem implements OffDocumentItem { | |||
/** | |||
* Process this extension immediately when | |||
* being handled by the area tree. | |||
*/ | |||
public static final int IMMEDIATELY = 0; | |||
/** | |||
* Process this extension after the next page is rendered | |||
* or prepared when being handled by the area tree. | |||
*/ | |||
public static final int AFTER_PAGE = 1; | |||
/** | |||
* Process this extension at the end of the document once | |||
* all pages have been fully rendered. | |||
*/ | |||
public static final int END_OF_DOC = 2; | |||
/** | |||
* Process this extension at the start of the document right | |||
* before the first page-sequence is processed. | |||
*/ | |||
public static final int START_OF_DOC = 2; | |||
/** Indicates in what phase the item should be processed. */ | |||
protected int whenToProcess = IMMEDIATELY; | |||
/** | |||
* Get an indicator of when this item should be processed | |||
* @return int constant (IMMEDIATELY, AFTER_PAGE, START_OF_DOC, END_OF_DOC) | |||
*/ | |||
public int getWhenToProcess() { | |||
return whenToProcess; | |||
} | |||
/** | |||
* Return a human-readable name for this ODI (for error messages, etc.) | |||
* @return String name of ODI | |||
*/ | |||
public abstract String getName(); | |||
} |
@@ -15,6 +15,7 @@ | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.area; | |||
// Java | |||
@@ -37,6 +38,7 @@ import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.apps.FormattingResults; | |||
import org.apache.fop.fo.FOEventHandler; | |||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||
import org.apache.fop.fo.pagination.PageSequence; | |||
import org.apache.fop.fo.pagination.Root; | |||
import org.apache.fop.fo.pagination.bookmarks.BookmarkTree; | |||
@@ -250,6 +252,26 @@ public class AreaTreeHandler extends FOEventHandler { | |||
} | |||
} | |||
/** @see org.apache.fop.fo.FOEventHandler */ | |||
public void startPageSequence(PageSequence pageSequence) { | |||
rootFObj = pageSequence.getRoot(); | |||
//extension attachments from fo:root | |||
wrapAndAddExtensionAttachments(rootFObj.getExtensionAttachments()); | |||
//extension attachments from fo:declarations | |||
if (rootFObj.getDeclarations() != null) { | |||
wrapAndAddExtensionAttachments(rootFObj.getDeclarations().getExtensionAttachments()); | |||
} | |||
} | |||
private void wrapAndAddExtensionAttachments(List list) { | |||
Iterator i = list.iterator(); | |||
while (i.hasNext()) { | |||
ExtensionAttachment attachment = (ExtensionAttachment)i.next(); | |||
addOffDocumentItem(new OffDocumentExtensionAttachment(attachment)); | |||
} | |||
} | |||
/** | |||
* End the PageSequence. | |||
* The PageSequence formats Pages and adds them to the AreaTree. | |||
@@ -264,8 +286,6 @@ public class AreaTreeHandler extends FOEventHandler { | |||
log.debug("Current heap size: " + (memoryNow / 1024L) + "Kb"); | |||
} | |||
rootFObj = pageSequence.getRoot(); | |||
// If no main flow, nothing to layout! | |||
if (pageSequence.getMainFlow() != null) { | |||
PageSequenceLayoutManager pageSLM; | |||
@@ -275,6 +295,11 @@ public class AreaTreeHandler extends FOEventHandler { | |||
} | |||
} | |||
/** | |||
* Called by the PageSequenceLayoutManager when it is finished with a page-sequence. | |||
* @param pageSequence the page-sequence just finished | |||
* @param pageCount The number of pages generated for the page-sequence | |||
*/ | |||
public void notifyPageSequenceFinished(PageSequence pageSequence, | |||
int pageCount) { | |||
this.results.haveFormattedPageSequence(pageSequence, |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 1999-2004 The Apache Software Foundation. | |||
* Copyright 1999-2005 The Apache Software Foundation. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
@@ -30,7 +30,7 @@ import org.apache.fop.fo.pagination.bookmarks.Bookmark; | |||
* its child bookmark-items, or a bookmark-item and the child | |||
* child bookmark-items under it. | |||
*/ | |||
public class BookmarkData extends OffDocumentItem implements Resolvable { | |||
public class BookmarkData extends AbstractOffDocumentItem implements Resolvable { | |||
private ArrayList subData = new ArrayList(); | |||
// bookmark-title for this fo:bookmark |
@@ -0,0 +1,55 @@ | |||
/* | |||
* Copyright 2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.area; | |||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||
/** | |||
* This class wraps ExtensionAttachments which cannot be transported inside the area tree but | |||
* need to be handled in the AreaTreeHandler. These attachments are schedules for processing | |||
* before the first page-sequence, i.e. at the start of the document. | |||
*/ | |||
public class OffDocumentExtensionAttachment implements OffDocumentItem { | |||
private ExtensionAttachment attachment; | |||
/** | |||
* Main constructor | |||
* @param attachment the extension attachment to wrap. | |||
*/ | |||
public OffDocumentExtensionAttachment(ExtensionAttachment attachment) { | |||
this.attachment = attachment; | |||
} | |||
/** @return the extension attachment. */ | |||
public ExtensionAttachment getAttachment() { | |||
return this.attachment; | |||
} | |||
/** @see org.apache.fop.area.OffDocumentItem#getWhenToProcess() */ | |||
public int getWhenToProcess() { | |||
return OffDocumentItem.IMMEDIATELY; | |||
} | |||
/** @see org.apache.fop.area.OffDocumentItem#getName() */ | |||
public String getName() { | |||
return attachment.getCategory(); | |||
} | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 1999-2004 The Apache Software Foundation. | |||
* Copyright 2004-2005 The Apache Software Foundation. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
@@ -19,45 +19,42 @@ | |||
package org.apache.fop.area; | |||
/** | |||
* Abstract base class for objects that are processed by the renderer outside | |||
* Interface for objects that are processed by the renderer outside | |||
* of the actual document. | |||
* This object can be handled by the renderer according to three | |||
* possibilities, IMMEDIATELY, AFTER_PAGE, or END_OF_DOC. | |||
* An object implementing this interface can be handled by the renderer according to these | |||
* possibilities: IMMEDIATELY, AFTER_PAGE or END_OF_DOC. | |||
*/ | |||
public abstract class OffDocumentItem { | |||
public interface OffDocumentItem { | |||
/** | |||
* Process this extension immediately when | |||
* being handled by the area tree. | |||
*/ | |||
public static final int IMMEDIATELY = 0; | |||
int IMMEDIATELY = 0; | |||
/** | |||
* Process this extension after the next page is rendered | |||
* or prepared when being handled by the area tree. | |||
*/ | |||
public static final int AFTER_PAGE = 1; | |||
int AFTER_PAGE = 1; | |||
/** | |||
* Process this extension at the end of the document once | |||
* all pages have been fully rendered. | |||
*/ | |||
public static final int END_OF_DOC = 2; | |||
int END_OF_DOC = 2; | |||
protected int whenToProcess = IMMEDIATELY; | |||
/** | |||
* Get an indicator of when this item should be processed | |||
* @return int constant (IMMEDIATELY, AFTER_PAGE, END_OF_DOC) | |||
*/ | |||
public int getWhenToProcess() { | |||
return whenToProcess; | |||
} | |||
int getWhenToProcess(); | |||
/** | |||
* Return a human-readable name for this ODI (for error messages, etc.) | |||
* @return String name of ODI | |||
*/ | |||
public abstract String getName(); | |||
String getName(); | |||
} |
@@ -25,7 +25,9 @@ import java.util.HashMap; | |||
* Element mapping class for all XSL-FO elements. | |||
*/ | |||
public class FOElementMapping extends ElementMapping { | |||
public static String URI = "http://www.w3.org/1999/XSL/Format"; | |||
/** The XSL-FO namespace URI */ | |||
public static final String URI = "http://www.w3.org/1999/XSL/Format"; | |||
/** | |||
* Basic constructor; inititializes the namespace URI for the fo: namespace |
@@ -29,17 +29,19 @@ import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||
import org.apache.fop.fo.extensions.ExtensionElementMapping; | |||
import org.apache.fop.fo.extensions.svg.SVGElementMapping; | |||
import org.apache.fop.fo.pagination.Root; | |||
import org.apache.fop.util.CharUtilities; | |||
/** | |||
* base class for nodes in the XML tree | |||
* Base class for nodes in the XML tree | |||
*/ | |||
public abstract class FONode implements Cloneable { | |||
protected static String FO_URI = FOElementMapping.URI; | |||
/** the XSL-FO namespace URI */ | |||
protected static final String FO_URI = FOElementMapping.URI; | |||
/** Parent FO node */ | |||
protected FONode parent; | |||
@@ -50,10 +52,12 @@ public abstract class FONode implements Cloneable { | |||
* information | |||
*/ | |||
public Locator locator; | |||
//TODO Make private or protected and access via getLocator() | |||
/** Logger for fo-tree related messages **/ | |||
private static Log log = LogFactory.getLog(FONode.class); | |||
protected static Log log = LogFactory.getLog(FONode.class); | |||
//TODO Remove getLogger() method! | |||
/** | |||
* Main constructor. | |||
* @param parent parent of this node | |||
@@ -68,9 +72,10 @@ public abstract class FONode implements Cloneable { | |||
* @param parent the intended parent of the clone | |||
* @param removeChildren if true, clean the list of child nodes | |||
* @return the cloned FO node | |||
* @throws FOPException if there's a problem while cloning the node | |||
*/ | |||
public FONode clone(FONode parent, boolean removeChildren) | |||
throws FOPException { | |||
throws FOPException { | |||
FONode foNode = (FONode) clone(); | |||
foNode.parent = parent; | |||
parent.addChildNode(foNode); | |||
@@ -86,8 +91,9 @@ public abstract class FONode implements Cloneable { | |||
protected Object clone() { | |||
try { | |||
return super.clone(); | |||
} catch (CloneNotSupportedException e) { } | |||
return null; | |||
} catch (CloneNotSupportedException e) { | |||
return null; | |||
} | |||
} | |||
/** | |||
@@ -100,6 +106,11 @@ public abstract class FONode implements Cloneable { | |||
} | |||
} | |||
/** @return the location information for this element or null, if not available */ | |||
public Locator getLocator() { | |||
return this.locator; | |||
} | |||
/** | |||
* Recursively goes up the FOTree hierarchy until the fo:root is found, | |||
* which returns the parent FOEventHandler. | |||
@@ -132,11 +143,15 @@ public abstract class FONode implements Cloneable { | |||
* @param elementName element name (e.g., "fo:block") | |||
* @param locator Locator object (ignored by default) | |||
* @param attlist Collection of attributes passed to us from the parser. | |||
* @param parent the property list of the parent node | |||
* @throws FOPException for errors or inconsistencies in the attributes | |||
*/ | |||
public void processNode(String elementName, Locator locator, | |||
Attributes attlist, PropertyList parent) throws FOPException { | |||
log.debug("name = " + elementName); | |||
if (log.isDebugEnabled()) { | |||
log.debug("Unhandled element: " + elementName | |||
+ (locator != null ? " at " + getLocatorString(locator) : "")); | |||
} | |||
} | |||
/** | |||
@@ -146,8 +161,10 @@ public abstract class FONode implements Cloneable { | |||
* @param foEventHandler The FOEventHandler where the PropertyListMaker | |||
* instance can be found. | |||
* @return A new property list. | |||
* @throws FOPException if there's a problem during processing | |||
*/ | |||
protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler) throws FOPException { | |||
protected PropertyList createPropertyList(PropertyList parent, FOEventHandler foEventHandler) | |||
throws FOPException { | |||
return null; | |||
} | |||
@@ -156,12 +173,15 @@ public abstract class FONode implements Cloneable { | |||
* incoming node is valid for the this (parent) node (e.g., checking to | |||
* see that fo:table is not an immediate child of fo:root) | |||
* called within FObj constructor | |||
* @param loc location in the FO source file | |||
* @param namespaceURI namespace of incoming node | |||
* @param localName (e.g. "table" for "fo:table") | |||
* @throws ValidationException if incoming node not valid for parent | |||
*/ | |||
protected void validateChildNode(Locator loc, String namespaceURI, String localName) | |||
throws ValidationException {} | |||
throws ValidationException { | |||
//nop | |||
} | |||
/** | |||
* Adds characters (does nothing here) | |||
@@ -179,25 +199,31 @@ public abstract class FONode implements Cloneable { | |||
} | |||
/** | |||
* | |||
*/ | |||
* Called after processNode() is called. Subclasses can do additional processing. | |||
* @throws FOPException if there's a problem during processing | |||
*/ | |||
protected void startOfNode() throws FOPException { | |||
// do nothing by default | |||
} | |||
/** | |||
* Primarily used for making final content model validation checks | |||
* and/or informing the FOEventHandler that the end of this FO | |||
* has been reached. | |||
* Primarily used for making final content model validation checks | |||
* and/or informing the FOEventHandler that the end of this FO | |||
* has been reached. | |||
* @throws FOPException if there's a problem during processing | |||
*/ | |||
protected void endOfNode() throws FOPException { | |||
// do nothing by default | |||
} | |||
/** | |||
* Adds a node as a child of this node. The default implementation of this method | |||
* just ignores any child node being added. | |||
* @param child child node to be added to the childNodes of this node | |||
* @throws FOPException if there's a problem during processing | |||
*/ | |||
protected void addChildNode(FONode child) throws FOPException { | |||
// do nothing by default | |||
} | |||
/** | |||
@@ -260,9 +286,10 @@ public abstract class FONode implements Cloneable { | |||
return "fox:" + localName; | |||
} else if (namespaceURI.equals(SVGElementMapping.URI)) { | |||
return "svg:" + localName; | |||
} else | |||
return "(Namespace URI: \"" + namespaceURI + "\", " + | |||
"Local Name: \"" + localName + "\")"; | |||
} else { | |||
return "(Namespace URI: \"" + namespaceURI + "\", " | |||
+ "Local Name: \"" + localName + "\")"; | |||
} | |||
} | |||
/** | |||
@@ -270,11 +297,12 @@ public abstract class FONode implements Cloneable { | |||
* (e.g., not specifying either an internal- or an external-destination | |||
* property for an FO:link) | |||
* @param problem text to display that indicates the problem | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void attributeError(String problem) | |||
throws ValidationException { | |||
throw new ValidationException(errorText(locator) + getName() + ", " + | |||
problem, locator); | |||
throws ValidationException { | |||
throw new ValidationException(errorText(locator) + getName() | |||
+ ", " + problem, locator); | |||
} | |||
/** | |||
@@ -283,7 +311,7 @@ public abstract class FONode implements Cloneable { | |||
* @param problem text to display that indicates the problem | |||
*/ | |||
protected void attributeWarning(String problem) { | |||
getLogger().warn(errorText(locator) + getName() + ", " + problem); | |||
log.warn(errorText(locator) + getName() + ", " + problem); | |||
} | |||
/** | |||
@@ -292,11 +320,12 @@ public abstract class FONode implements Cloneable { | |||
* @param loc org.xml.sax.Locator object of the error (*not* parent node) | |||
* @param nsURI namespace URI of incoming invalid node | |||
* @param lName local name (i.e., no prefix) of incoming node | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void tooManyNodesError(Locator loc, String nsURI, String lName) | |||
throws ValidationException { | |||
throw new ValidationException(errorText(loc) + "For " + getName() + | |||
", only one " + getNodeString(nsURI, lName) + " may be declared.", | |||
throws ValidationException { | |||
throw new ValidationException(errorText(loc) + "For " + getName() | |||
+ ", only one " + getNodeString(nsURI, lName) + " may be declared.", | |||
loc); | |||
} | |||
@@ -306,11 +335,12 @@ public abstract class FONode implements Cloneable { | |||
* This overrloaded method helps make the caller code better self-documenting | |||
* @param loc org.xml.sax.Locator object of the error (*not* parent node) | |||
* @param offendingNode incoming node that would cause a duplication. | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void tooManyNodesError(Locator loc, String offendingNode) | |||
throws ValidationException { | |||
throw new ValidationException(errorText(loc) + "For " + getName() + | |||
", only one " + offendingNode + " may be declared.", loc); | |||
throws ValidationException { | |||
throw new ValidationException(errorText(loc) + "For " + getName() | |||
+ ", only one " + offendingNode + " may be declared.", loc); | |||
} | |||
/** | |||
@@ -319,6 +349,7 @@ public abstract class FONode implements Cloneable { | |||
* @param loc org.xml.sax.Locator object of the error (*not* parent node) | |||
* @param tooLateNode string name of node that should be earlier in document | |||
* @param tooEarlyNode string name of node that should be later in document | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void nodesOutOfOrderError(Locator loc, String tooLateNode, | |||
String tooEarlyNode) throws ValidationException { | |||
@@ -332,9 +363,10 @@ public abstract class FONode implements Cloneable { | |||
* @param loc org.xml.sax.Locator object of the error (*not* parent node) | |||
* @param nsURI namespace URI of incoming invalid node | |||
* @param lName local name (i.e., no prefix) of incoming node | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void invalidChildError(Locator loc, String nsURI, String lName) | |||
throws ValidationException { | |||
throws ValidationException { | |||
invalidChildError(loc, nsURI, lName, null); | |||
} | |||
@@ -345,62 +377,71 @@ public abstract class FONode implements Cloneable { | |||
* @param nsURI namespace URI of incoming invalid node | |||
* @param lName local name (i.e., no prefix) of incoming node | |||
* @param ruleViolated text explanation of problem | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void invalidChildError(Locator loc, String nsURI, String lName, | |||
String ruleViolated) | |||
throws ValidationException { | |||
throw new ValidationException(errorText(loc) + getNodeString(nsURI, lName) + | |||
" is not a valid child element of " + getName() | |||
String ruleViolated) | |||
throws ValidationException { | |||
throw new ValidationException(errorText(loc) + getNodeString(nsURI, lName) | |||
+ " is not a valid child element of " + getName() | |||
+ ((ruleViolated != null) ? ": " + ruleViolated : "."), loc); | |||
} | |||
/** | |||
* Helper function to throw an error caused by missing mandatory child elements. | |||
* E.g., fo:layout-master-set not having any page-master child element. | |||
* @param contentModel The XSL Content Model for the fo: object or a similar description indicating the necessary child elements. | |||
* @param contentModel The XSL Content Model for the fo: object or a similar description | |||
* indicating the necessary child elements. | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void missingChildElementError(String contentModel) | |||
throws ValidationException { | |||
throw new ValidationException(errorText(locator) + getName() + | |||
" is missing child elements. \nRequired Content Model: " | |||
throws ValidationException { | |||
throw new ValidationException(errorText(locator) + getName() | |||
+ " is missing child elements. \nRequired Content Model: " | |||
+ contentModel, locator); | |||
} | |||
/** | |||
* Helper function to throw an error caused by missing mandatory properties | |||
* @param propertyName the name of the missing property. | |||
* @throws ValidationException the validation error provoked by the method call | |||
*/ | |||
protected void missingPropertyError(String propertyName) | |||
throws ValidationException { | |||
throw new ValidationException(errorText(locator) + getName() + | |||
" is missing required \"" + propertyName + "\" property.", locator); | |||
throws ValidationException { | |||
throw new ValidationException(errorText(locator) + getName() | |||
+ " is missing required \"" + propertyName + "\" property.", locator); | |||
} | |||
/** | |||
* Helper function to return "Error (line#/column#)" string for | |||
* Helper function to return "Error(line#/column#)" string for | |||
* above exception messages | |||
* @param loc org.xml.sax.Locator object | |||
* @return String opening error text | |||
*/ | |||
protected static String errorText(Locator loc) { | |||
if (loc == null) { | |||
return "Error(Unknown location): "; | |||
} else { | |||
return "Error(" + loc.getLineNumber() + "/" + loc.getColumnNumber() + "): "; | |||
} | |||
return "Error(" + getLocatorString(loc) + "): "; | |||
} | |||
/** | |||
* Helper function to return "Warning (line#/column#)" string for | |||
* Helper function to return "Warning(line#/column#)" string for | |||
* warning messages | |||
* @param loc org.xml.sax.Locator object | |||
* @return String opening warning text | |||
*/ | |||
protected static String warningText(Locator loc) { | |||
return "Warning(" + getLocatorString(loc) + "): "; | |||
} | |||
/** | |||
* Helper function to format a Locator instance. | |||
* @param loc org.xml.sax.Locator object | |||
* @return String the formatted text | |||
*/ | |||
protected static String getLocatorString(Locator loc) { | |||
if (loc == null) { | |||
return "Warning(Unknown location): "; | |||
return "Unknown location"; | |||
} else { | |||
return "Warning(" + loc.getLineNumber() + "/" + loc.getColumnNumber() + "): "; | |||
return loc.getLineNumber() + "/" + loc.getColumnNumber(); | |||
} | |||
} | |||
@@ -429,5 +470,16 @@ public abstract class FONode implements Cloneable { | |||
return Constants.FO_UNKNOWN_NODE; | |||
} | |||
/** | |||
* This method is overridden by extension elements and allows the extension element | |||
* to return a pass-through attachment which the parent formatting objects should simply | |||
* carry with them but otherwise ignore. This mechanism is used to pass non-standard | |||
* information from the FO tree through to the layout engine and the renderers. | |||
* @return the extension attachment if one is created by the extension element, null otherwise. | |||
*/ | |||
public ExtensionAttachment getExtensionAttachment() { | |||
return null; | |||
} | |||
} | |||
@@ -135,6 +135,7 @@ public class FOTreeBuilder extends DefaultHandler { | |||
addElementMapping("org.apache.fop.fo.extensions.svg.SVGElementMapping"); | |||
addElementMapping("org.apache.fop.fo.extensions.svg.BatikExtensionElementMapping"); | |||
addElementMapping("org.apache.fop.fo.extensions.ExtensionElementMapping"); | |||
addElementMapping("org.apache.fop.render.ps.extensions.PSExtensionElementMapping"); | |||
// add mappings from available services | |||
Iterator providers = Service.providers(ElementMapping.class); |
@@ -18,6 +18,7 @@ | |||
package org.apache.fop.fo; | |||
import java.util.Collections; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.ListIterator; | |||
@@ -26,6 +27,7 @@ import java.util.Set; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.datatypes.PercentBase; | |||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||
import org.apache.fop.fo.flow.Marker; | |||
import org.apache.fop.fo.properties.PropertyMaker; | |||
import org.xml.sax.Attributes; | |||
@@ -35,11 +37,16 @@ import org.xml.sax.Locator; | |||
* Base class for representation of formatting objects and their processing. | |||
*/ | |||
public abstract class FObj extends FONode implements Constants { | |||
public static PropertyMaker[] propertyListTable = null; | |||
/** the list of property makers */ | |||
private static PropertyMaker[] propertyListTable = null; | |||
/** The immediate child nodes of this node. */ | |||
public List childNodes = null; | |||
protected List childNodes = null; | |||
/** The list of extension attachments, null if none */ | |||
private List extensionAttachments = null; | |||
/** Used to indicate if this FO is either an Out Of Line FO (see rec) | |||
or a descendant of one. Used during validateChildNode() FO | |||
validation. | |||
@@ -64,7 +71,7 @@ public abstract class FObj extends FONode implements Constants { | |||
// determine if isOutOfLineFODescendant should be set | |||
if (parent != null && parent instanceof FObj) { | |||
if (((FObj)parent).getIsOutOfLineFODescendant() == true) { | |||
if (((FObj)parent).getIsOutOfLineFODescendant()) { | |||
isOutOfLineFODescendant = true; | |||
} else { | |||
int foID = getNameId(); | |||
@@ -97,6 +104,15 @@ public abstract class FObj extends FONode implements Constants { | |||
} | |||
return fobj; | |||
} | |||
/** | |||
* Returns the PropertyMaker for a given property ID. | |||
* @param propId the property ID | |||
* @return the requested Property Maker | |||
*/ | |||
public static PropertyMaker getPropertyMakerFor(int propId) { | |||
return propertyListTable[propId]; | |||
} | |||
/** | |||
* @see org.apache.fop.fo.FONode#processNode | |||
@@ -111,6 +127,7 @@ public abstract class FObj extends FONode implements Constants { | |||
/** | |||
* Create a default property list for this element. | |||
* @see org.apache.fop.fo.FONode | |||
*/ | |||
protected PropertyList createPropertyList(PropertyList parent, | |||
FOEventHandler foEventHandler) throws FOPException { | |||
@@ -122,7 +139,7 @@ public abstract class FObj extends FONode implements Constants { | |||
* Must be overridden in all FObj subclasses that have properties | |||
* applying to it. | |||
* @param pList the PropertyList where the properties can be found. | |||
* @throws FOPException | |||
* @throws FOPException if there is a problem binding the values | |||
*/ | |||
public void bind(PropertyList pList) throws FOPException { | |||
} | |||
@@ -132,16 +149,18 @@ public abstract class FObj extends FONode implements Constants { | |||
* Most formatting objects can have an id that can be referenced. | |||
* This methods checks that the id isn't already used by another | |||
* fo and sets the id attribute of this object. | |||
* @param id ID to check | |||
* @throws ValidationException if the ID is already defined elsewhere | |||
*/ | |||
protected void checkId(String id) throws ValidationException { | |||
protected void checkId(String id) throws ValidationException { | |||
if (!id.equals("")) { | |||
Set idrefs = getFOEventHandler().getIDReferences(); | |||
if (!idrefs.contains(id)) { | |||
idrefs.add(id); | |||
} else { | |||
throw new ValidationException("Property id \"" + id + | |||
"\" previously used; id values must be unique" + | |||
" in document.", locator); | |||
throw new ValidationException("Property id \"" + id | |||
+ "\" previously used; id values must be unique" | |||
+ " in document.", locator); | |||
} | |||
} | |||
} | |||
@@ -158,14 +177,20 @@ public abstract class FObj extends FONode implements Constants { | |||
* @see org.apache.fop.fo.FONode#addChildNode(FONode) | |||
*/ | |||
protected void addChildNode(FONode child) throws FOPException { | |||
if (PropertySets.canHaveMarkers(getNameId()) && | |||
child.getNameId() == FO_MARKER) { | |||
addMarker((Marker) child); | |||
if (PropertySets.canHaveMarkers(getNameId()) && child.getNameId() == FO_MARKER) { | |||
addMarker((Marker)child); | |||
} else { | |||
if (childNodes == null) { | |||
childNodes = new java.util.ArrayList(); | |||
ExtensionAttachment attachment = child.getExtensionAttachment(); | |||
if (attachment != null) { | |||
//This removes the element from the normal children, so no layout manager | |||
//is being created for them as they are only additional information. | |||
addExtensionAttachment(attachment); | |||
} else { | |||
if (childNodes == null) { | |||
childNodes = new java.util.ArrayList(); | |||
} | |||
childNodes.add(child); | |||
} | |||
childNodes.add(child); | |||
} | |||
} | |||
@@ -194,6 +219,7 @@ public abstract class FObj extends FONode implements Constants { | |||
* Assign the size of a layout dimension to the key. | |||
* @param key the Layout dimension, from PercentBase. | |||
* @param dimension The layout length. | |||
* TODO Remove when possible! | |||
*/ | |||
public void setLayoutDimension(PercentBase.LayoutDimension key, int dimension) { | |||
if (layoutDimension == null) { | |||
@@ -206,6 +232,7 @@ public abstract class FObj extends FONode implements Constants { | |||
* Assign the size of a layout dimension to the key. | |||
* @param key the Layout dimension, from PercentBase. | |||
* @param dimension The layout length. | |||
* TODO Remove when possible! | |||
*/ | |||
public void setLayoutDimension(PercentBase.LayoutDimension key, float dimension) { | |||
if (layoutDimension == null) { | |||
@@ -218,6 +245,7 @@ public abstract class FObj extends FONode implements Constants { | |||
* Return the size associated with the key. | |||
* @param key The layout dimension key. | |||
* @return the length. | |||
* TODO Remove when possible! | |||
*/ | |||
public Number getLayoutDimension(PercentBase.LayoutDimension key) { | |||
if (layoutDimension != null) { | |||
@@ -349,14 +377,14 @@ public abstract class FObj extends FONode implements Constants { | |||
* @return true if a member, false if not | |||
*/ | |||
protected boolean isBlockItem(String nsURI, String lName) { | |||
return (FO_URI.equals(nsURI) && | |||
(lName.equals("block") | |||
|| lName.equals("table") | |||
|| lName.equals("table-and-caption") | |||
|| lName.equals("block-container") | |||
|| lName.equals("list-block") | |||
|| lName.equals("float") | |||
|| isNeutralItem(nsURI, lName))); | |||
return (FO_URI.equals(nsURI) | |||
&& (lName.equals("block") | |||
|| lName.equals("table") | |||
|| lName.equals("table-and-caption") | |||
|| lName.equals("block-container") | |||
|| lName.equals("list-block") | |||
|| lName.equals("float") | |||
|| isNeutralItem(nsURI, lName))); | |||
} | |||
/** | |||
@@ -368,21 +396,22 @@ public abstract class FObj extends FONode implements Constants { | |||
* @return true if a member, false if not | |||
*/ | |||
protected boolean isInlineItem(String nsURI, String lName) { | |||
return (FO_URI.equals(nsURI) && | |||
(lName.equals("bidi-override") | |||
|| lName.equals("character") | |||
|| lName.equals("external-graphic") | |||
|| lName.equals("instream-foreign-object") | |||
|| lName.equals("inline") | |||
|| lName.equals("inline-container") | |||
|| lName.equals("leader") | |||
|| lName.equals("page-number") | |||
|| lName.equals("page-number-citation") | |||
|| lName.equals("basic-link") | |||
|| (lName.equals("multi-toggle") | |||
&& (getNameId() == FO_MULTI_CASE || findAncestor(FO_MULTI_CASE) > 0)) | |||
|| (lName.equals("footnote") && !isOutOfLineFODescendant) | |||
|| isNeutralItem(nsURI, lName))); | |||
return (FO_URI.equals(nsURI) | |||
&& (lName.equals("bidi-override") | |||
|| lName.equals("character") | |||
|| lName.equals("external-graphic") | |||
|| lName.equals("instream-foreign-object") | |||
|| lName.equals("inline") | |||
|| lName.equals("inline-container") | |||
|| lName.equals("leader") | |||
|| lName.equals("page-number") | |||
|| lName.equals("page-number-citation") | |||
|| lName.equals("basic-link") | |||
|| (lName.equals("multi-toggle") | |||
&& (getNameId() == FO_MULTI_CASE | |||
|| findAncestor(FO_MULTI_CASE) > 0)) | |||
|| (lName.equals("footnote") && !isOutOfLineFODescendant) | |||
|| isNeutralItem(nsURI, lName))); | |||
} | |||
/** | |||
@@ -406,12 +435,12 @@ public abstract class FObj extends FONode implements Constants { | |||
* @return true if a member, false if not | |||
*/ | |||
protected boolean isNeutralItem(String nsURI, String lName) { | |||
return (FO_URI.equals(nsURI) && | |||
(lName.equals("multi-switch") | |||
|| lName.equals("multi-properties") | |||
|| lName.equals("wrapper") | |||
|| (!isOutOfLineFODescendant && lName.equals("float")) | |||
|| lName.equals("retrieve-marker"))); | |||
return (FO_URI.equals(nsURI) | |||
&& (lName.equals("multi-switch") | |||
|| lName.equals("multi-properties") | |||
|| lName.equals("wrapper") | |||
|| (!isOutOfLineFODescendant && lName.equals("float")) | |||
|| lName.equals("retrieve-marker"))); | |||
} | |||
/** | |||
@@ -433,5 +462,33 @@ public abstract class FObj extends FONode implements Constants { | |||
} | |||
return -1; | |||
} | |||
/** | |||
* Add a new extension attachment to this FObj. See org.apache.fop.fo.FONode for details. | |||
* @param attachment the attachment to add. | |||
*/ | |||
public void addExtensionAttachment(ExtensionAttachment attachment) { | |||
if (attachment == null) { | |||
throw new NullPointerException("Parameter attachment must not be null"); | |||
} | |||
if (extensionAttachments == null) { | |||
extensionAttachments = new java.util.ArrayList(); | |||
} | |||
if (log.isDebugEnabled()) { | |||
getLogger().debug("ExtensionAttachment of category " + attachment.getCategory() | |||
+ " added to " + getName() + ": " + attachment); | |||
} | |||
extensionAttachments.add(attachment); | |||
} | |||
/** @return the extension attachments of this FObj. */ | |||
public List getExtensionAttachments() { | |||
if (extensionAttachments == null) { | |||
return Collections.EMPTY_LIST; | |||
} else { | |||
return extensionAttachments; | |||
} | |||
} | |||
} | |||
@@ -452,7 +452,7 @@ abstract public class PropertyList { | |||
if (propId < 1 || propId > Constants.PROPERTY_COUNT) { | |||
return null; | |||
} else { | |||
return FObj.propertyListTable[propId]; | |||
return FObj.getPropertyMakerFor(propId); | |||
} | |||
} | |||
@@ -0,0 +1,38 @@ | |||
/* | |||
* Copyright 2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.fo.extensions; | |||
/** | |||
* This interface is implemented by objects that are returned by special extension element | |||
* through the FONode.getExtensionAttachment() method. Such objects are carried in the FO tree | |||
* and made available to the layout managers that support processing extension attachments or | |||
* support passing them on to the area tree where they can be picked up by renderers. | |||
* <p> | |||
* NOTE: Classes which implement this interface need to be Serializable! | |||
*/ | |||
public interface ExtensionAttachment { | |||
/** | |||
* This method returns a category URI that allows a processor (layout manager or renderer) | |||
* to determine if it supports this object. | |||
* @return the category URI | |||
*/ | |||
String getCategory(); | |||
} |
@@ -327,4 +327,10 @@ public class InstreamForeignObject extends FObj { | |||
protected void addChildNode(FONode child) throws FOPException { | |||
super.addChildNode(child); | |||
} | |||
/** @return the XMLObj child node of the instream-foreign-object. */ | |||
public XMLObj getChildXMLObj() { | |||
return (XMLObj) childNodes.get(0); | |||
} | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 1999-2004 The Apache Software Foundation. | |||
* Copyright 1999-2005 The Apache Software Foundation. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
@@ -20,7 +20,6 @@ package org.apache.fop.fo.pagination; | |||
// Java | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.xml.sax.Locator; | |||
@@ -30,8 +29,6 @@ import org.apache.fop.fo.FONode; | |||
import org.apache.fop.fo.FObj; | |||
import org.apache.fop.fo.PropertyList; | |||
import org.apache.fop.fo.ValidationException; | |||
import org.apache.fop.fo.XMLObj; | |||
/** | |||
* Declarations formatting object. | |||
@@ -43,7 +40,6 @@ import org.apache.fop.fo.XMLObj; | |||
public class Declarations extends FObj { | |||
private Map colorProfiles = null; | |||
private List external = null; | |||
/** | |||
* @param parent FONode that is the parent of this object | |||
@@ -62,11 +58,11 @@ public class Declarations extends FObj { | |||
/** | |||
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String) | |||
XSL 1.0: (color-profile)+ (and non-XSL NS nodes) | |||
FOP/XSL 1.1: (color-profile)* (and non-XSL NS nodes) | |||
* XSL 1.0: (color-profile)+ (and non-XSL NS nodes) | |||
* FOP/XSL 1.1: (color-profile)* (and non-XSL NS nodes) | |||
*/ | |||
protected void validateChildNode(Locator loc, String nsURI, String localName) | |||
throws ValidationException { | |||
throws ValidationException { | |||
if (FO_URI.equals(nsURI)) { | |||
if (!localName.equals("color-profile")) { | |||
invalidChildError(loc, nsURI, localName); | |||
@@ -75,8 +71,9 @@ public class Declarations extends FObj { | |||
} | |||
/** | |||
* At the end of this element sort out the child into | |||
* a hashmap of color profiles and a list of external xml. | |||
* At the end of this element sort out the children into | |||
* a hashmap of color profiles and a list of extension attachments. | |||
* @see org.apache.fop.fo.FONode#endOfNode() | |||
*/ | |||
protected void endOfNode() throws FOPException { | |||
if (childNodes != null) { | |||
@@ -97,13 +94,9 @@ public class Declarations extends FObj { | |||
} else { | |||
getLogger().warn("color-profile-name required for color profile"); | |||
} | |||
} else if (node instanceof XMLObj) { | |||
if (external == null) { | |||
external = new java.util.ArrayList(); | |||
} | |||
external.add(node); | |||
} else { | |||
getLogger().warn("invalid element " + node.getName() + " inside declarations"); | |||
getLogger().debug("Ignoring element " + node.getName() | |||
+ " inside fo:declarations."); | |||
} | |||
} | |||
} |
@@ -106,8 +106,8 @@ public class SimplePageMaster extends FObj { | |||
*/ | |||
protected void endOfNode() throws FOPException { | |||
if (!hasRegionBody) { | |||
missingChildElementError("(region-body, region-before?," + | |||
" region-after?, region-start?, region-end?)"); | |||
missingChildElementError( | |||
"(region-body, region-before?, region-after?, region-start?, region-end?)"); | |||
} | |||
} | |||
@@ -182,8 +182,12 @@ public class SimplePageMaster extends FObj { | |||
/** | |||
* @see org.apache.fop.fo.FONode#addChildNode(FONode) | |||
*/ | |||
protected void addChildNode(FONode child) { | |||
addRegion((Region)child); | |||
protected void addChildNode(FONode child) throws FOPException { | |||
if (child instanceof Region) { | |||
addRegion((Region)child); | |||
} else { | |||
super.addChildNode(child); | |||
} | |||
} | |||
/** | |||
@@ -229,45 +233,32 @@ public class SimplePageMaster extends FObj { | |||
return false; | |||
} | |||
/** | |||
* Return the Common Margin Properties-Block. | |||
*/ | |||
/** @return the Common Margin Properties-Block. */ | |||
public CommonMarginBlock getCommonMarginBlock() { | |||
return commonMarginBlock; | |||
} | |||
/** | |||
* Return "master-name" property. | |||
*/ | |||
/** @return "master-name" property. */ | |||
public String getMasterName() { | |||
return masterName; | |||
} | |||
/** | |||
* Return the "page-width" property. | |||
*/ | |||
/** @return the "page-width" property. */ | |||
public Length getPageWidth() { | |||
return pageWidth; | |||
} | |||
/** | |||
* Return the "page-height" property. | |||
*/ | |||
/** @return the "page-height" property. */ | |||
public Length getPageHeight() { | |||
return pageHeight; | |||
} | |||
/** | |||
* Return the "writing-mode" property. | |||
*/ | |||
/** @return the "writing-mode" property. */ | |||
public int getWritingMode() { | |||
return writingMode; | |||
} | |||
/** | |||
* Return the "reference-orientation" property. | |||
*/ | |||
/** @return the "reference-orientation" property. */ | |||
public int getReferenceOrientation() { | |||
return referenceOrientation.getValue(); | |||
} |
@@ -57,7 +57,7 @@ public class InstreamForeignObjectLM extends LeafNodeLayoutManager { | |||
* @return the viewport inline area | |||
*/ | |||
private Viewport getInlineArea() { | |||
XMLObj child = (XMLObj) fobj.childNodes.get(0); | |||
XMLObj child = (XMLObj) fobj.getChildXMLObj(); | |||
// viewport size is determined by block-progression-dimension | |||
// and inline-progression-dimension |
@@ -22,6 +22,7 @@ package org.apache.fop.render.ps; | |||
import java.awt.Color; | |||
import java.awt.geom.Rectangle2D; | |||
import java.io.IOException; | |||
import java.io.LineNumberReader; | |||
import java.io.OutputStream; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -34,6 +35,9 @@ import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.area.BlockViewport; | |||
import org.apache.fop.area.CTM; | |||
import org.apache.fop.area.LineArea; | |||
import org.apache.fop.area.OffDocumentExtensionAttachment; | |||
import org.apache.fop.area.OffDocumentItem; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.RegionViewport; | |||
import org.apache.fop.area.Trait; | |||
@@ -46,6 +50,7 @@ import org.apache.fop.area.inline.TextArea; | |||
import org.apache.fop.datatypes.ColorType; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.fo.Constants; | |||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||
import org.apache.fop.fonts.FontSetup; | |||
import org.apache.fop.fonts.Typeface; | |||
import org.apache.fop.image.EPSImage; | |||
@@ -54,6 +59,7 @@ import org.apache.fop.image.ImageFactory; | |||
import org.apache.fop.image.XMLImage; | |||
import org.apache.fop.render.AbstractPathOrientedRenderer; | |||
import org.apache.fop.render.RendererContext; | |||
import org.apache.fop.render.ps.extensions.PSSetupCode; | |||
import org.apache.fop.util.CharUtilities; | |||
import org.w3c.dom.Document; | |||
@@ -93,7 +99,11 @@ public class PSRenderer extends AbstractPathOrientedRenderer { | |||
private boolean ioTrouble = false; | |||
private boolean inTextMode = false; | |||
private boolean firstPageSequenceReceived = false; | |||
/** Used to temporarily store PSSetupCode instance until they can be written. */ | |||
private List setupCodeList; | |||
/** | |||
* @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) | |||
*/ | |||
@@ -568,17 +578,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer { | |||
gen.writeDSCComment(DSCConstants.BEGIN_DEFAULTS); | |||
gen.writeDSCComment(DSCConstants.END_DEFAULTS); | |||
//Prolog | |||
gen.writeDSCComment(DSCConstants.BEGIN_PROLOG); | |||
PSProcSets.writeFOPStdProcSet(gen); | |||
PSProcSets.writeFOPEPSProcSet(gen); | |||
gen.writeDSCComment(DSCConstants.END_PROLOG); | |||
//Setup | |||
gen.writeDSCComment(DSCConstants.BEGIN_SETUP); | |||
PSProcSets.writeFontDict(gen, fontInfo); | |||
gen.writeln("FOPFonts begin"); | |||
gen.writeDSCComment(DSCConstants.END_SETUP); | |||
//Prolog and Setup written right before the first page-sequence, see startPageSequence() | |||
} | |||
/** | |||
@@ -592,6 +592,76 @@ public class PSRenderer extends AbstractPathOrientedRenderer { | |||
gen.flush(); | |||
} | |||
/** @see org.apache.fop.render.Renderer */ | |||
public void processOffDocumentItem(OffDocumentItem oDI) { | |||
log.debug("Handling OffDocumentItem: " + oDI.getName()); | |||
if (oDI instanceof OffDocumentExtensionAttachment) { | |||
ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)oDI).getAttachment(); | |||
if (PSSetupCode.CATEGORY.equals(attachment.getCategory())) { | |||
PSSetupCode setupCode = (PSSetupCode)attachment; | |||
if (setupCodeList == null) { | |||
setupCodeList = new java.util.ArrayList(); | |||
} | |||
setupCodeList.add(setupCode); | |||
} | |||
} | |||
super.processOffDocumentItem(oDI); | |||
} | |||
/** @see org.apache.fop.render.Renderer#startPageSequence(org.apache.fop.area.LineArea) */ | |||
public void startPageSequence(LineArea seqTitle) { | |||
super.startPageSequence(seqTitle); | |||
if (!firstPageSequenceReceived) { | |||
//Do this only once, as soon as we have all the content for the Setup section! | |||
try { | |||
//Prolog | |||
gen.writeDSCComment(DSCConstants.BEGIN_PROLOG); | |||
PSProcSets.writeFOPStdProcSet(gen); | |||
PSProcSets.writeFOPEPSProcSet(gen); | |||
gen.writeDSCComment(DSCConstants.END_PROLOG); | |||
//Setup | |||
gen.writeDSCComment(DSCConstants.BEGIN_SETUP); | |||
writeSetupCodeList(setupCodeList, "SetupCode"); | |||
PSProcSets.writeFontDict(gen, fontInfo); | |||
gen.writeln("FOPFonts begin"); | |||
gen.writeDSCComment(DSCConstants.END_SETUP); | |||
} catch (IOException ioe) { | |||
handleIOTrouble(ioe); | |||
} | |||
firstPageSequenceReceived = true; | |||
} | |||
} | |||
/** | |||
* Formats and writes a List of PSSetupCode instances to the output stream. | |||
* @param setupCodeList a List of PSSetupCode instances | |||
* @param type the type of code section | |||
*/ | |||
private void writeSetupCodeList(List setupCodeList, String type) throws IOException { | |||
if (setupCodeList != null) { | |||
Iterator i = setupCodeList.iterator(); | |||
while (i.hasNext()) { | |||
PSSetupCode setupCode = (PSSetupCode)i.next(); | |||
gen.commentln("%FOPBegin" + type + ": (" | |||
+ (setupCode.getName() != null ? setupCode.getName() : "") | |||
+ ")"); | |||
LineNumberReader reader = new LineNumberReader( | |||
new java.io.StringReader(setupCode.getContent())); | |||
String line; | |||
while ((line = reader.readLine()) != null) { | |||
line = line.trim(); | |||
if (line.length() > 0) { | |||
gen.writeln(line.trim()); | |||
} | |||
} | |||
gen.commentln("%FOPEnd" + type); | |||
i.remove(); | |||
} | |||
} | |||
} | |||
/** | |||
* @see org.apache.fop.render.Renderer#renderPage(PageViewport) | |||
*/ | |||
@@ -641,7 +711,23 @@ public class PSRenderer extends AbstractPathOrientedRenderer { | |||
} | |||
gen.writeDSCComment(DSCConstants.PAGE_RESOURCES, | |||
new Object[] {PSGenerator.ATEND}); | |||
gen.commentln("%FOPSimplePageMaster: " + page.getSPM().getMasterName()); | |||
gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); | |||
//Handle PSSetupCode instances on simple-page-master | |||
if (page.getSPM().getExtensionAttachments().size() > 0) { | |||
List list = new java.util.ArrayList(); | |||
//Extract all PSSetupCode instances from the attachment list on the s-p-m | |||
Iterator i = page.getSPM().getExtensionAttachments().iterator(); | |||
while (i.hasNext()) { | |||
ExtensionAttachment attachment = (ExtensionAttachment)i.next(); | |||
if (PSSetupCode.CATEGORY.equals(attachment.getCategory())) { | |||
list.add(attachment); | |||
} | |||
} | |||
writeSetupCodeList(list, "PageSetupCode"); | |||
} | |||
if (rotate) { | |||
gen.writeln(Math.round(pspageheight) + " 0 translate"); | |||
gen.writeln("90 rotate"); | |||
@@ -652,7 +738,6 @@ public class PSRenderer extends AbstractPathOrientedRenderer { | |||
+ Math.round(pspageheight) + "]"); | |||
gen.writeln("/ImagingBBox null"); | |||
gen.writeln(">> setpagedevice"); | |||
//gen.writeln("0.001 0.001 scale"); | |||
concatMatrix(1, 0, 0, -1, 0, pageheight / 1000f); | |||
gen.writeDSCComment(DSCConstants.END_PAGE_SETUP); |
@@ -0,0 +1,96 @@ | |||
/* | |||
* Copyright 2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.ps.extensions; | |||
// FOP | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.fo.FONode; | |||
import org.apache.fop.fo.PropertyList; | |||
import org.apache.fop.fo.ValidationException; | |||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||
import org.xml.sax.Attributes; | |||
import org.xml.sax.Locator; | |||
/** | |||
* Base class for the PostScript-specific extension elements. | |||
*/ | |||
public abstract class AbstractPSExtensionObject extends FONode { | |||
private PSSetupCode setupCode = new PSSetupCode(); | |||
/** | |||
* @see org.apache.fop.fo.FONode#FONode(FONode) | |||
*/ | |||
public AbstractPSExtensionObject(FONode parent) { | |||
super(parent); | |||
} | |||
/** | |||
* @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String) | |||
* here, blocks XSL FO's from having non-FO parents. | |||
*/ | |||
protected void validateChildNode(Locator loc, String nsURI, String localName) | |||
throws ValidationException { | |||
if (FO_URI.equals(nsURI)) { | |||
invalidChildError(loc, nsURI, localName); | |||
} | |||
} | |||
/** @see org.apache.fop.fo.FONode */ | |||
protected void addCharacters(char[] data, int start, int length, | |||
PropertyList pList, Locator locator) { | |||
if (setupCode.getContent() != null) { | |||
StringBuffer sb = new StringBuffer(setupCode.getContent()); | |||
sb.append(data, start, length - start); | |||
setupCode.setContent(sb.toString()); | |||
} else { | |||
setupCode.setContent(new String(data, start, length - start)); | |||
} | |||
} | |||
/** @see org.apache.fop.fo.XMLObj#getNameSpace() */ | |||
public String getNameSpace() { | |||
return PSExtensionElementMapping.NAMESPACE; | |||
} | |||
/** @see org.apache.fop.fo.FONode#processNode */ | |||
public void processNode(String elementName, Locator locator, | |||
Attributes attlist, PropertyList propertyList) | |||
throws FOPException { | |||
String name = attlist.getValue("name"); | |||
if (name != null && name.length() > 0) { | |||
setupCode.setName(name); | |||
} | |||
} | |||
/** @see org.apache.fop.fo.FONode#endOfNode() */ | |||
protected void endOfNode() throws FOPException { | |||
super.endOfNode(); | |||
String s = setupCode.getContent(); | |||
if (s == null || s.length() == 0) { | |||
missingChildElementError("#PCDATA"); | |||
} | |||
} | |||
/** @see org.apache.fop.fo.FONode#getExtensionAttachment() */ | |||
public ExtensionAttachment getExtensionAttachment() { | |||
return this.setupCode; | |||
} | |||
} | |||
@@ -0,0 +1,58 @@ | |||
/* | |||
* Copyright 2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.ps.extensions; | |||
import org.apache.fop.fo.FONode; | |||
import org.apache.fop.fo.ElementMapping; | |||
/** | |||
* This class provides the element mapping for the PostScript-specific extensions. | |||
*/ | |||
public class PSExtensionElementMapping extends ElementMapping { | |||
/** Namespace for the extension */ | |||
public static final String NAMESPACE = "http://xmlgraphics.apache.org/fop/postscript"; | |||
/** Main constructor */ | |||
public PSExtensionElementMapping() { | |||
this.namespaceURI = NAMESPACE; | |||
} | |||
/** @see org.apache.fop.fo.ElementMapping#initialize() */ | |||
protected void initialize() { | |||
if (foObjs == null) { | |||
foObjs = new java.util.HashMap(); | |||
foObjs.put("ps-setup-code", new PSSetupCodeMaker()); | |||
foObjs.put("ps-page-setup-code", new PSPageSetupCodeMaker()); | |||
} | |||
} | |||
static class PSSetupCodeMaker extends ElementMapping.Maker { | |||
public FONode make(FONode parent) { | |||
return new PSSetupCodeElement(parent); | |||
} | |||
} | |||
static class PSPageSetupCodeMaker extends ElementMapping.Maker { | |||
public FONode make(FONode parent) { | |||
return new PSPageSetupCodeElement(parent); | |||
} | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
/* | |||
* Copyright 2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.ps.extensions; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.fo.Constants; | |||
import org.apache.fop.fo.FONode; | |||
import org.apache.fop.fo.ValidationException; | |||
/** | |||
* Extension element for fox:ps-page-setup-code. | |||
*/ | |||
public class PSPageSetupCodeElement extends AbstractPSExtensionObject { | |||
/** | |||
* Main constructor | |||
* @param parent parent FO node | |||
*/ | |||
public PSPageSetupCodeElement(FONode parent) { | |||
super(parent); | |||
} | |||
/** @see org.apache.fop.fo.FONode#startOfNode() */ | |||
protected void startOfNode() throws FOPException { | |||
super.startOfNode(); | |||
if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { | |||
throw new ValidationException(getName() + " must be a child of fo:simple-page-master."); | |||
} | |||
} | |||
/** @see org.apache.fop.fo.FONode#getName() */ | |||
public String getName() { | |||
return "fox:ps-page-setup-code"; | |||
} | |||
} |
@@ -0,0 +1,89 @@ | |||
/* | |||
* Copyright 2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.ps.extensions; | |||
import java.io.Serializable; | |||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||
/** | |||
* This is the pass-through value object for the PostScript extension. | |||
*/ | |||
public class PSSetupCode implements ExtensionAttachment, Serializable { | |||
/** The category URI for this extension attachment. */ | |||
public static final String CATEGORY = "apache:fop:extensions:postscript"; | |||
private String name; | |||
private String content; | |||
/** | |||
* No-argument contructor. | |||
*/ | |||
public PSSetupCode() { | |||
//nop | |||
} | |||
/** | |||
* Default constructor. | |||
* @param name the name of the setup code object, may be null | |||
* @param content the content of the setup code object | |||
*/ | |||
public PSSetupCode(String name, String content) { | |||
this.name = name; | |||
this.content = content; | |||
} | |||
/** @return the content */ | |||
public String getContent() { | |||
return content; | |||
} | |||
/** | |||
* Sets the content for the setup code object. | |||
* @param content The content to set. | |||
*/ | |||
public void setContent(String content) { | |||
this.content = content; | |||
} | |||
/** @return the name */ | |||
public String getName() { | |||
return name; | |||
} | |||
/** | |||
* Sets the name of the setup code object. | |||
* @param name The name to set. | |||
*/ | |||
public void setName(String name) { | |||
this.name = name; | |||
} | |||
/** @see org.apache.fop.fo.extensions.ExtensionAttachment#getCategory() */ | |||
public String getCategory() { | |||
return CATEGORY; | |||
} | |||
/** @see java.lang.Object#toString() */ | |||
public String toString() { | |||
return "PSSetupCode(name=" + getName() + ")"; | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
/* | |||
* Copyright 2005 The Apache Software Foundation. | |||
* | |||
* Licensed 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.ps.extensions; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.fo.Constants; | |||
import org.apache.fop.fo.FONode; | |||
import org.apache.fop.fo.ValidationException; | |||
/** | |||
* Extension element for fox:ps-setup-code. | |||
*/ | |||
public class PSSetupCodeElement extends AbstractPSExtensionObject { | |||
/** | |||
* Main constructor | |||
* @param parent parent FO node | |||
*/ | |||
public PSSetupCodeElement(FONode parent) { | |||
super(parent); | |||
} | |||
/** @see org.apache.fop.fo.FONode#startOfNode() */ | |||
protected void startOfNode() throws FOPException { | |||
super.startOfNode(); | |||
if (parent.getNameId() != Constants.FO_DECLARATIONS) { | |||
throw new ValidationException(getName() + " must be a child of fo:declarations."); | |||
} | |||
} | |||
/** @see org.apache.fop.fo.FONode#getName() */ | |||
public String getName() { | |||
return "fox:ps-setup-code"; | |||
} | |||
} |