diff options
author | Jeremias Maerki <jeremias@apache.org> | 2008-07-22 15:48:39 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2008-07-22 15:48:39 +0000 |
commit | 8091bd11210ac68aa3289532643e42b66545a495 (patch) | |
tree | 0c500f554120284fef9debb77c463d738804ff3b /src/java/org/apache/fop/render/intermediate | |
parent | cd64af07c5661e82a7121a2ac6ad756a3b2e91e9 (diff) | |
download | xmlgraphics-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')
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(); |