aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/render/intermediate
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2008-07-22 15:48:39 +0000
committerJeremias Maerki <jeremias@apache.org>2008-07-22 15:48:39 +0000
commit8091bd11210ac68aa3289532643e42b66545a495 (patch)
tree0c500f554120284fef9debb77c463d738804ff3b /src/java/org/apache/fop/render/intermediate
parentcd64af07c5661e82a7121a2ac6ad756a3b2e91e9 (diff)
downloadxmlgraphics-fop-8091bd11210ac68aa3289532643e42b66545a495.tar.gz
xmlgraphics-fop-8091bd11210ac68aa3289532643e42b66545a495.zip
Started the IFParser.
Started a PDF painter. Factored out common code to PDFRenderingUtil. Smaller infrastructure changes for the new IF (like MIME type reporting). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@678780 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/render/intermediate')
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFPainter.java167
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractIFPainterMaker.java11
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFPainter.java5
-rw-r--r--src/java/org/apache/fop/render/intermediate/AffineTransformArrayParser.java146
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFPainter.java8
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFPainterConfigurator.java35
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFParser.java552
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFRenderer.java5
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFSerializer.java5
9 files changed, 921 insertions, 13 deletions
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFPainter.java b/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFPainter.java
new file mode 100644
index 000000000..860de7946
--- /dev/null
+++ b/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFPainter.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.intermediate;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.List;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.fonts.CustomFontCollection;
+import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.base14.Base14FontCollection;
+import org.apache.fop.render.DefaultFontResolver;
+
+/**
+ * Abstract base class for binary-writing IFPainter implementations.
+ */
+public abstract class AbstractBinaryWritingIFPainter extends AbstractIFPainter {
+
+ /** The output stream to write the document to */
+ protected OutputStream outputStream;
+
+ private boolean ownOutputStream;
+
+ /** Font configuration */
+ protected FontInfo fontInfo;
+
+ /** Font resolver */
+ protected FontResolver fontResolver = null;
+
+ /** list of fonts */
+ protected List/*<EmbedFontInfo>*/ embedFontInfoList = null;
+
+ /** {@inheritDoc} */
+ public void setResult(Result result) throws IFException {
+ if (result instanceof StreamResult) {
+ StreamResult streamResult = (StreamResult)result;
+ OutputStream out = streamResult.getOutputStream();
+ if (out == null) {
+ if (streamResult.getWriter() != null) {
+ throw new IllegalArgumentException(
+ "FOP cannot use a Writer. Please supply an OutputStream!");
+ }
+ try {
+ URL url = new URL(streamResult.getSystemId());
+ File f = FileUtils.toFile(url);
+ if (f != null) {
+ out = new java.io.FileOutputStream(f);
+ } else {
+ out = url.openConnection().getOutputStream();
+ }
+ } catch (IOException ioe) {
+ throw new IFException("I/O error while opening output stream" , ioe);
+ }
+ out = new java.io.BufferedOutputStream(out);
+ this.ownOutputStream = true;
+ }
+ if (out == null) {
+ throw new IllegalArgumentException("Need a StreamResult with an OutputStream");
+ }
+ this.outputStream = out;
+ } else {
+ throw new UnsupportedOperationException(
+ "Unsupported Result subclass: " + result.getClass().getName());
+ }
+ }
+
+ /**
+ * Adds a font list to current list of fonts
+ * @param fontList a font info list
+ */
+ public void addFontList(List/*<EmbedFontInfo>*/ fontList) {
+ if (embedFontInfoList == null) {
+ setFontList(fontList);
+ } else {
+ embedFontInfoList.addAll(fontList);
+ }
+ }
+
+ /**
+ * @param embedFontInfoList list of available fonts
+ */
+ public void setFontList(List/*<EmbedFontInfo>*/ embedFontInfoList) {
+ this.embedFontInfoList = embedFontInfoList;
+ }
+
+ /**
+ * @return list of available embedded fonts
+ */
+ public List/*<EmbedFontInfo>*/ getFontList() {
+ return this.embedFontInfoList;
+ }
+
+ /**
+ * Returns the {@code FontResolver} used by this painter.
+ * @return the font resolver
+ */
+ public FontResolver getFontResolver() {
+ if (this.fontResolver == null) {
+ this.fontResolver = new DefaultFontResolver(getUserAgent());
+ }
+ return this.fontResolver;
+ }
+
+ /**
+ * Returns the {@code FontInfo} object.
+ * @return the font info
+ */
+ public FontInfo getFontInfo() {
+ return this.fontInfo;
+ }
+
+ public void setFontInfo(FontInfo fontInfo) {
+ this.fontInfo = fontInfo;
+ }
+
+ /**
+ * Set up the font info
+ *
+ * @param inFontInfo font info to set up
+ */
+ public void setupFontInfo(FontInfo inFontInfo) {
+ setFontInfo(inFontInfo);
+ FontManager fontManager = getUserAgent().getFactory().getFontManager();
+ FontCollection[] fontCollections = new FontCollection[] {
+ new Base14FontCollection(fontManager.isBase14KerningEnabled()),
+ new CustomFontCollection(getFontResolver(), getFontList())
+ };
+ fontManager.setup(getFontInfo(), fontCollections);
+ }
+
+ /** {@inheritDoc} */
+ public void endDocument() throws IFException {
+ if (this.ownOutputStream) {
+ IOUtils.closeQuietly(this.outputStream);
+ this.outputStream = null;
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractIFPainterMaker.java b/src/java/org/apache/fop/render/intermediate/AbstractIFPainterMaker.java
index 273f90170..aa653cd3e 100644
--- a/src/java/org/apache/fop/render/intermediate/AbstractIFPainterMaker.java
+++ b/src/java/org/apache/fop/render/intermediate/AbstractIFPainterMaker.java
@@ -45,15 +45,12 @@ public abstract class AbstractIFPainterMaker {
public abstract String[] getSupportedMimeTypes();
/**
- * Returns a renderer config object that can be used to
+ * Returns a configurator object that can be used to
* configure the painter.
- * @param userAgent user agent
- * @return a config object that can be used to configure the painter
+ * @param userAgent the user agent
+ * @return a configurator object that can be used to configure the painter
*/
- /*
- public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
- return null;
- }*/
+ public abstract IFPainterConfigurator getConfigurator(FOUserAgent userAgent);
/**
* Indicates whether a specific MIME type is supported by this painter.
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFPainter.java b/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFPainter.java
index 166b6df20..bb226dd0c 100644
--- a/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFPainter.java
+++ b/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFPainter.java
@@ -57,11 +57,6 @@ public abstract class AbstractXMLWritingIFPainter extends AbstractIFPainter {
protected ContentHandler handler;
/** {@inheritDoc} */
- public ContentHandler getContentHandler() {
- return this.handler;
- }
-
- /** {@inheritDoc} */
public void setResult(Result result) throws IFException {
if (result instanceof SAXResult) {
SAXResult saxResult = (SAXResult)result;
diff --git a/src/java/org/apache/fop/render/intermediate/AffineTransformArrayParser.java b/src/java/org/apache/fop/render/intermediate/AffineTransformArrayParser.java
new file mode 100644
index 000000000..36a783427
--- /dev/null
+++ b/src/java/org/apache/fop/render/intermediate/AffineTransformArrayParser.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.intermediate;
+
+import java.awt.geom.AffineTransform;
+import java.io.Reader;
+import java.util.List;
+
+import org.apache.batik.parser.ParseException;
+import org.apache.batik.parser.TransformListHandler;
+import org.apache.batik.parser.TransformListParser;
+
+/**
+ * This class parses a sequence of transformations into an array of {@code AffineTransform}
+ * instances.
+ */
+public class AffineTransformArrayParser implements TransformListHandler {
+
+ private List transforms;
+
+ /**
+ * Utility method for creating an AffineTransform array.
+ * @param r The reader used to read the transform specification.
+ * @return the AffineTransform array
+ * @throws ParseException if there's a parse error
+ */
+ public static AffineTransform[] createAffineTransform(Reader r)
+ throws ParseException {
+ TransformListParser p = new TransformListParser();
+ AffineTransformArrayParser th = new AffineTransformArrayParser();
+
+ p.setTransformListHandler(th);
+ p.parse(r);
+
+ return th.getAffineTransforms();
+ }
+
+ /**
+ * Utility method for creating an AffineTransform.
+ * @param s The transform specification.
+ * @return the AffineTransform array
+ * @throws ParseException if there's a parse error
+ */
+ public static AffineTransform[] createAffineTransform(String s)
+ throws ParseException {
+ TransformListParser p = new TransformListParser();
+ AffineTransformArrayParser th = new AffineTransformArrayParser();
+
+ p.setTransformListHandler(th);
+ p.parse(s);
+
+ return th.getAffineTransforms();
+ }
+
+ /**
+ * Returns the AffineTransform array initialized during the last parsing.
+ * @return the array or null if this handler has not been used by
+ * a parser.
+ */
+ public AffineTransform[] getAffineTransforms() {
+ if (this.transforms == null) {
+ return null;
+ } else {
+ int count = this.transforms.size();
+ return (AffineTransform[])this.transforms.toArray(new AffineTransform[count]);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void startTransformList() throws ParseException {
+ this.transforms = new java.util.ArrayList();
+ }
+
+ /** {@inheritDoc} */
+ public void matrix(float a, float b, float c, float d, float e, float f)
+ throws ParseException {
+ this.transforms.add(new AffineTransform(a, b, c, d, e, f));
+ }
+
+ /** {@inheritDoc} */
+ public void rotate(float theta) throws ParseException {
+ this.transforms.add(AffineTransform.getRotateInstance(Math.toRadians(theta)));
+ }
+
+ /** {@inheritDoc} */
+ public void rotate(float theta, float cx, float cy) throws ParseException {
+ AffineTransform at
+ = AffineTransform.getRotateInstance(Math.toRadians(theta), cx, cy);
+ this.transforms.add(at);
+ }
+
+ /** {@inheritDoc} */
+ public void translate(float tx) throws ParseException {
+ AffineTransform at = AffineTransform.getTranslateInstance(tx, 0);
+ this.transforms.add(at);
+ }
+
+ /** {@inheritDoc} */
+ public void translate(float tx, float ty) throws ParseException {
+ AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
+ this.transforms.add(at);
+ }
+
+ /** {@inheritDoc} */
+ public void scale(float sx) throws ParseException {
+ this.transforms.add(AffineTransform.getScaleInstance(sx, sx));
+ }
+
+ /** {@inheritDoc} */
+ public void scale(float sx, float sy) throws ParseException {
+ this.transforms.add(AffineTransform.getScaleInstance(sx, sy));
+ }
+
+ /** {@inheritDoc} */
+ public void skewX(float skx) throws ParseException {
+ this.transforms.add
+ (AffineTransform.getShearInstance(Math.tan(Math.toRadians(skx)), 0));
+ }
+
+ /** {@inheritDoc} */
+ public void skewY(float sky) throws ParseException {
+ this.transforms.add
+ (AffineTransform.getShearInstance(0, Math.tan(Math.toRadians(sky))));
+ }
+
+ /** {@inheritDoc} */
+ public void endTransformList() throws ParseException {
+ }
+}
diff --git a/src/java/org/apache/fop/render/intermediate/IFPainter.java b/src/java/org/apache/fop/render/intermediate/IFPainter.java
index 83045b6bc..44e02fe68 100644
--- a/src/java/org/apache/fop/render/intermediate/IFPainter.java
+++ b/src/java/org/apache/fop/render/intermediate/IFPainter.java
@@ -97,6 +97,12 @@ public interface IFPainter {
boolean supportsPagesOutOfOrder();
/**
+ * Returns the MIME type of the output format that is generated by this implementation.
+ * @return the MIME type
+ */
+ String getMimeType();
+
+ /**
* Indicates the start of a document. This method may only be called once before any other
* event method.
* @throws IFException if an error occurs while handling this event
@@ -141,7 +147,7 @@ public interface IFPainter {
/**
* Indicates the start of a new page.
- * @param index the index of the page within the document (0-based)
+ * @param index the index of the page (0-based)
* @param name the page name (usually the formatted page number)
* @param size the size of the page (equivalent to the MediaBox in PDF)
* @throws IFException if an error occurs while handling this event
diff --git a/src/java/org/apache/fop/render/intermediate/IFPainterConfigurator.java b/src/java/org/apache/fop/render/intermediate/IFPainterConfigurator.java
new file mode 100644
index 000000000..e42f52665
--- /dev/null
+++ b/src/java/org/apache/fop/render/intermediate/IFPainterConfigurator.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.intermediate;
+
+import org.apache.fop.apps.FOPException;
+
+/**
+ * This interface is implemented by classes that configure an {@code IFPainter} instance.
+ */
+public interface IFPainterConfigurator {
+
+ /**
+ * Configures a painter.
+ * @param painter the painter instance
+ * @throws FOPException if an error occurs while configuring the object
+ */
+ void configure(IFPainter painter) throws FOPException;
+}
diff --git a/src/java/org/apache/fop/render/intermediate/IFParser.java b/src/java/org/apache/fop/render/intermediate/IFParser.java
new file mode 100644
index 000000000..ba0a6c60b
--- /dev/null
+++ b/src/java/org/apache/fop/render/intermediate/IFParser.java
@@ -0,0 +1,552 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.intermediate;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.Map;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.ElementMappingRegistry;
+import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.util.ColorUtil;
+import org.apache.fop.util.ContentHandlerFactory;
+import org.apache.fop.util.ContentHandlerFactoryRegistry;
+import org.apache.fop.util.ConversionUtils;
+import org.apache.fop.util.DefaultErrorListener;
+
+/**
+ * This is a parser for the intermediate format XML which converts the intermediate file into
+ * {@code IFPainter} events.
+ */
+public class IFParser implements IFConstants {
+
+ /** Logger instance */
+ protected static Log log = LogFactory.getLog(IFParser.class);
+
+ private static SAXTransformerFactory tFactory
+ = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
+
+ /**
+ * Parses an intermediate file and paints it.
+ * @param src the Source instance pointing to the intermediate file
+ * @param painter the intermediate format painter used to process the IF events
+ * @param userAgent the user agent
+ * @throws TransformerException if an error occurs while parsing the area tree XML
+ */
+ public void parse(Source src, IFPainter painter, FOUserAgent userAgent)
+ throws TransformerException {
+ Transformer transformer = tFactory.newTransformer();
+ transformer.setErrorListener(new DefaultErrorListener(log));
+
+ SAXResult res = new SAXResult(getContentHandler(painter, userAgent));
+
+ transformer.transform(src, res);
+ }
+
+ /**
+ * Creates a new ContentHandler instance that you can send the area tree XML to. The parsed
+ * pages are added to the AreaTreeModel instance you pass in as a parameter.
+ * @param painter the intermediate format painter used to process the IF events
+ * @param userAgent the user agent
+ * @return the ContentHandler instance to receive the SAX stream from the area tree XML
+ */
+ public ContentHandler getContentHandler(IFPainter painter, FOUserAgent userAgent) {
+ ElementMappingRegistry elementMappingRegistry
+ = userAgent.getFactory().getElementMappingRegistry();
+ return new Handler(painter, userAgent, elementMappingRegistry);
+ }
+
+ private static class Handler extends DefaultHandler {
+
+ private Map elementHandlers = new java.util.HashMap();
+
+ private IFPainter painter;
+ private FOUserAgent userAgent;
+ private ElementMappingRegistry elementMappingRegistry;
+
+ private Attributes lastAttributes;
+
+ private StringBuffer content = new StringBuffer();
+ private boolean ignoreCharacters = true;
+
+ //private Stack delegateStack = new Stack();
+ private int delegateDepth;
+ private ContentHandler delegate;
+ private DOMImplementation domImplementation;
+
+
+ public Handler(IFPainter painter, FOUserAgent userAgent,
+ ElementMappingRegistry elementMappingRegistry) {
+ this.painter = painter;
+ this.userAgent = userAgent;
+ this.elementMappingRegistry = elementMappingRegistry;
+ elementHandlers.put("document", new DocumentHandler());
+ elementHandlers.put("header", new DocumentHeaderHandler());
+ elementHandlers.put("page-sequence", new PageSequenceHandler());
+ elementHandlers.put("page", new PageHandler());
+ elementHandlers.put("page-header", new PageHeaderHandler());
+ elementHandlers.put("content", new PageContentHandler());
+ elementHandlers.put("page-trailer", new PageTrailerHandler());
+ //Page content
+ elementHandlers.put("box", new BoxHandler());
+ elementHandlers.put("font", new FontHandler());
+ elementHandlers.put("text", new TextHandler());
+ elementHandlers.put("rect", new RectHandler());
+ }
+
+
+ /** {@inheritDoc} */
+ public void startElement(String uri, String localName, String qName, Attributes attributes)
+ throws SAXException {
+ if (delegate != null) {
+ //delegateStack.push(qName);
+ delegateDepth++;
+ delegate.startElement(uri, localName, qName, attributes);
+ } else if (domImplementation != null) {
+ //domImplementation is set so we need to start a new DOM building sub-process
+ TransformerHandler handler;
+ try {
+ handler = tFactory.newTransformerHandler();
+ } catch (TransformerConfigurationException e) {
+ throw new SAXException("Error creating a new TransformerHandler", e);
+ }
+ Document doc = domImplementation.createDocument(uri, qName, null);
+ //It's easier to work with an empty document, so remove the root element
+ doc.removeChild(doc.getDocumentElement());
+ handler.setResult(new DOMResult(doc));
+ //Area parent = (Area)areaStack.peek();
+ //((ForeignObject)parent).setDocument(doc);
+
+ //activate delegate for nested foreign document
+ domImplementation = null; //Not needed anymore now
+ this.delegate = handler;
+ //delegateStack.push(qName);
+ delegateDepth++;
+ delegate.startDocument();
+ delegate.startElement(uri, localName, qName, attributes);
+ } else {
+ lastAttributes = attributes;
+ boolean handled = true;
+ if (NAMESPACE.equals(uri)) {
+ ElementHandler elementHandler = (ElementHandler)elementHandlers.get(localName);
+ content.setLength(0);
+ ignoreCharacters = true;
+ if (elementHandler != null) {
+ ignoreCharacters = elementHandler.ignoreCharacters();
+ try {
+ elementHandler.startElement(attributes);
+ } catch (IFException ife) {
+ handleIFException(ife);
+ }
+ } else if ("extension-attachments".equals(localName)) {
+ //TODO implement me
+ } else {
+ handled = false;
+ }
+ } else {
+ ContentHandlerFactoryRegistry registry
+ = userAgent.getFactory().getContentHandlerFactoryRegistry();
+ ContentHandlerFactory factory = registry.getFactory(uri);
+ if (factory != null) {
+ delegate = factory.createContentHandler();
+ //delegateStack.push(qName);
+ delegateDepth++;
+ delegate.startDocument();
+ delegate.startElement(uri, localName, qName, attributes);
+ } else {
+ handled = false;
+ }
+ }
+ if (!handled) {
+ if (uri == null || uri.length() == 0) {
+ throw new SAXException("Unhandled element " + localName
+ + " in namespace: " + uri);
+ } else {
+ log.warn("Unhandled element " + localName
+ + " in namespace: " + uri);
+ }
+ }
+ }
+ }
+
+ private void handleIFException(IFException ife) throws SAXException {
+ if (ife.getCause() instanceof SAXException) {
+ //unwrap
+ throw (SAXException)ife.getCause();
+ } else {
+ //wrap
+ throw new SAXException(ife);
+ }
+ }
+
+
+ /** {@inheritDoc} */
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (delegate != null) {
+ delegate.endElement(uri, localName, qName);
+ //delegateStack.pop();
+ delegateDepth--;
+ if (delegateDepth == 0) {
+ delegate.endDocument();
+ if (delegate instanceof ContentHandlerFactory.ObjectSource) {
+ Object obj = ((ContentHandlerFactory.ObjectSource)delegate).getObject();
+ handleExternallyGeneratedObject(obj);
+ }
+ delegate = null; //Sub-document is processed, return to normal processing
+ }
+ } else {
+ if (NAMESPACE.equals(uri)) {
+ ElementHandler elementHandler = (ElementHandler)elementHandlers.get(localName);
+ if (elementHandler != null) {
+ try {
+ elementHandler.endElement();
+ } catch (IFException ife) {
+ handleIFException(ife);
+ }
+ content.setLength(0);
+ }
+ ignoreCharacters = true;
+ } else {
+ //log.debug("Ignoring " + localName + " in namespace: " + uri);
+ }
+ }
+ }
+
+ // ============== Element handlers for the intermediate format =============
+
+ private static interface ElementHandler {
+ void startElement(Attributes attributes) throws IFException, SAXException;
+ void endElement() throws IFException;
+ boolean ignoreCharacters();
+ }
+
+ private abstract class AbstractElementHandler implements ElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException, SAXException {
+ //nop
+ }
+
+ public void endElement() throws IFException {
+ //nop
+ }
+
+ public boolean ignoreCharacters() {
+ return true;
+ }
+ }
+
+ private class DocumentHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ painter.startDocument();
+ }
+
+ public void endElement() throws IFException {
+ painter.endDocument();
+ }
+
+ }
+
+ private class DocumentHeaderHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ painter.startDocumentHeader();
+ }
+
+ public void endElement() throws IFException {
+ painter.endDocumentHeader();
+ }
+
+ }
+
+ private class PageSequenceHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ String id = attributes.getValue("id");
+ painter.startPageSequence(id);
+ }
+
+ public void endElement() throws IFException {
+ painter.endPageSequence();
+ }
+
+ }
+
+ private class PageHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ int index = Integer.parseInt(attributes.getValue("index"));
+ String name = attributes.getValue("name");
+ int width = Integer.parseInt(attributes.getValue("width"));
+ int height = Integer.parseInt(attributes.getValue("height"));
+ painter.startPage(index, name, new Dimension(width, height));
+ }
+
+ public void endElement() throws IFException {
+ painter.endPage();
+ }
+
+ }
+
+ private class PageHeaderHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ painter.startPageHeader();
+ }
+
+ public void endElement() throws IFException {
+ painter.endPageHeader();
+ }
+
+ }
+
+ private class PageContentHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ painter.startPageContent();
+ }
+
+ public void endElement() throws IFException {
+ painter.endPageContent();
+ }
+
+ }
+
+ private class PageTrailerHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ painter.startPageTrailer();
+ }
+
+ public void endElement() throws IFException {
+ painter.endPageTrailer();
+ }
+
+ }
+
+ private class BoxHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ String transform = attributes.getValue("transform");
+ AffineTransform[] transforms
+ = AffineTransformArrayParser.createAffineTransform(transform);
+ //TODO Incomplete implementation
+ painter.startBox(transforms, null, false);
+ }
+
+ public void endElement() throws IFException {
+ painter.endBox();
+ }
+
+ }
+
+ private class FontHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ String family = attributes.getValue("family");
+ String style = attributes.getValue("style");
+ Integer weight = getAttributeAsInteger(attributes, "weight");
+ String variant = attributes.getValue("variant");
+ Integer size = getAttributeAsInteger(attributes, "size");
+ Color color;
+ try {
+ color = getAttributeAsColor(attributes, "color");
+ } catch (PropertyException pe) {
+ throw new IFException("Error parsing the color attribute", pe);
+ }
+ painter.setFont(family, style, weight, variant, size, color);
+ }
+
+ }
+
+ private class TextHandler extends AbstractElementHandler {
+
+ public void endElement() throws IFException {
+ int x = Integer.parseInt(lastAttributes.getValue("x"));
+ int y = Integer.parseInt(lastAttributes.getValue("y"));
+ int[] dx = getAttributeAsIntArray(lastAttributes, "dx");
+ int[] dy = getAttributeAsIntArray(lastAttributes, "dy");
+ painter.drawText(x, y, dx, dy, content.toString());
+ }
+
+ public boolean ignoreCharacters() {
+ return false;
+ }
+
+ }
+
+ private class RectHandler extends AbstractElementHandler {
+
+ public void startElement(Attributes attributes) throws IFException {
+ int x = Integer.parseInt(lastAttributes.getValue("x"));
+ int y = Integer.parseInt(lastAttributes.getValue("y"));
+ int width = Integer.parseInt(lastAttributes.getValue("width"));
+ int height = Integer.parseInt(lastAttributes.getValue("height"));
+ Color fillColor;
+ try {
+ fillColor = getAttributeAsColor(attributes, "fill");
+ } catch (PropertyException pe) {
+ throw new IFException("Error parsing the fill attribute", pe);
+ }
+ Color strokeColor;
+ try {
+ strokeColor = getAttributeAsColor(attributes, "stroke");
+ } catch (PropertyException pe) {
+ throw new IFException("Error parsing the stroke attribute", pe);
+ }
+ painter.drawRect(new Rectangle(x, y, width, height), fillColor, strokeColor);
+ }
+
+ }
+
+
+ // ====================================================================
+
+
+ private void assertObjectOfClass(Object obj, Class clazz) {
+ if (!clazz.isInstance(obj)) {
+ throw new IllegalStateException("Object is not an instance of "
+ + clazz.getName() + " but of " + obj.getClass().getName());
+ }
+ }
+
+ /**
+ * Handles objects created by "sub-parsers" that implement the ObjectSource interface.
+ * An example of object handled here are ExtensionAttachments.
+ * @param obj the Object to be handled.
+ */
+ protected void handleExternallyGeneratedObject(Object obj) {
+ if (obj instanceof ExtensionAttachment) {
+ ExtensionAttachment attachment = (ExtensionAttachment)obj;
+ //TODO Implement me
+ /*
+ if (this.currentPageViewport == null) {
+ this.treeModel.handleOffDocumentItem(
+ new OffDocumentExtensionAttachment(attachment));
+ } else {
+ this.currentPageViewport.addExtensionAttachment(attachment);
+ }
+ */
+ } else {
+ log.warn("Don't know how to handle externally generated object: " + obj);
+ }
+ }
+
+ private static boolean getAttributeAsBoolean(Attributes attributes, String name,
+ boolean defaultValue) {
+ String s = attributes.getValue(name);
+ if (s == null) {
+ return defaultValue;
+ } else {
+ return Boolean.valueOf(s).booleanValue();
+ }
+ }
+
+ private static int getAttributeAsInteger(Attributes attributes, String name,
+ int defaultValue) {
+ String s = attributes.getValue(name);
+ if (s == null) {
+ return defaultValue;
+ } else {
+ return Integer.parseInt(s);
+ }
+ }
+
+ private static Integer getAttributeAsInteger(Attributes attributes, String name) {
+ String s = attributes.getValue(name);
+ if (s == null) {
+ return null;
+ } else {
+ return new Integer(s);
+ }
+ }
+
+ private Color getAttributeAsColor(Attributes attributes, String name)
+ throws PropertyException {
+ String s = attributes.getValue(name);
+ if (s == null) {
+ return null;
+ } else {
+ return ColorUtil.parseColorString(userAgent, s);
+ }
+ }
+
+ private static Rectangle2D getAttributeAsRectangle2D(Attributes attributes, String name) {
+ String s = attributes.getValue(name).trim();
+ double[] values = ConversionUtils.toDoubleArray(s, "\\s");
+ if (values.length != 4) {
+ throw new IllegalArgumentException("Rectangle must consist of 4 double values!");
+ }
+ return new Rectangle2D.Double(values[0], values[1], values[2], values[3]);
+ }
+
+ private static Rectangle getAttributeAsRectangle(Attributes attributes, String name) {
+ String s = attributes.getValue(name).trim();
+ int[] values = ConversionUtils.toIntArray(s, "\\s");
+ if (values.length != 4) {
+ throw new IllegalArgumentException("Rectangle must consist of 4 int values!");
+ }
+ return new Rectangle(values[0], values[1], values[2], values[3]);
+ }
+
+ private static int[] getAttributeAsIntArray(Attributes attributes, String name) {
+ String s = attributes.getValue(name);
+ if (s == null) {
+ return null;
+ } else {
+ return ConversionUtils.toIntArray(s.trim(), "\\s");
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (delegate != null) {
+ delegate.characters(ch, start, length);
+ } else if (!ignoreCharacters) {
+ this.content.append(ch, start, length);
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/intermediate/IFRenderer.java b/src/java/org/apache/fop/render/intermediate/IFRenderer.java
index 83e7b5397..c4243a86a 100644
--- a/src/java/org/apache/fop/render/intermediate/IFRenderer.java
+++ b/src/java/org/apache/fop/render/intermediate/IFRenderer.java
@@ -121,6 +121,7 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
public void setupFontInfo(FontInfo inFontInfo) {
if (mimic != null) {
mimic.setupFontInfo(inFontInfo);
+ this.fontInfo = inFontInfo;
} else {
super.setupFontInfo(inFontInfo);
}
@@ -164,6 +165,10 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
this.painter = new IFSerializer();
}
this.painter.setUserAgent(getUserAgent());
+ if (this.painter instanceof AbstractBinaryWritingIFPainter) {
+ //TODO THIS IS UGLY. FIX ME!!!
+ ((AbstractBinaryWritingIFPainter)this.painter).setFontInfo(fontInfo);
+ }
this.painter.setResult(result);
}
super.startRenderer(null);
diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializer.java b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
index 41cecd1e7..8cfbcad11 100644
--- a/src/java/org/apache/fop/render/intermediate/IFSerializer.java
+++ b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
@@ -56,6 +56,11 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst
}
/** {@inheritDoc} */
+ public String getMimeType() {
+ return MIME_TYPE;
+ }
+
+ /** {@inheritDoc} */
public void startDocument() throws IFException {
try {
handler.startDocument();