diff options
Diffstat (limited to 'src/sandbox/org/apache/fop/render')
-rw-r--r-- | src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java | 116 | ||||
-rw-r--r-- | src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java | 446 | ||||
-rw-r--r-- | src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java | 272 | ||||
-rw-r--r-- | src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java (renamed from src/sandbox/org/apache/fop/render/svg/SVGPainterMaker.java) | 19 | ||||
-rw-r--r-- | src/sandbox/org/apache/fop/render/svg/SVGPainter.java | 490 | ||||
-rw-r--r-- | src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java (renamed from src/sandbox/org/apache/fop/render/svg/SVGPrintPainter.java) | 37 | ||||
-rw-r--r-- | src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java (renamed from src/sandbox/org/apache/fop/render/svg/SVGPrintPainterMaker.java) | 19 |
7 files changed, 755 insertions, 644 deletions
diff --git a/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java b/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java new file mode 100644 index 000000000..fbb6728ca --- /dev/null +++ b/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java @@ -0,0 +1,116 @@ +/* + * 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.svg; + +import org.xml.sax.SAXException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.xmp.Metadata; + +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.render.intermediate.AbstractXMLWritingIFDocumentHandler; +import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator; +import org.apache.fop.render.intermediate.IFException; +import org.apache.fop.render.intermediate.IFState; +import org.apache.fop.render.java2d.Java2DUtil; + +/** + * Abstract base class for SVG Painter implementations. + */ +public abstract class AbstractSVGDocumentHandler extends AbstractXMLWritingIFDocumentHandler + implements SVGConstants { + + /** logging instance */ + private static Log log = LogFactory.getLog(AbstractSVGDocumentHandler.class); + + /** Font configuration */ + protected FontInfo fontInfo; + + /** Holds the intermediate format state */ + protected IFState state; + + private static final int MODE_NORMAL = 0; + private static final int MODE_TEXT = 1; + + private int mode = MODE_NORMAL; + + /** {@inheritDoc} */ + protected String getMainNamespace() { + return NAMESPACE; + } + + /** {@inheritDoc} */ + public FontInfo getFontInfo() { + return this.fontInfo; + } + + /** {@inheritDoc} */ + public void setFontInfo(FontInfo fontInfo) { + this.fontInfo = fontInfo; + } + + /** {@inheritDoc} */ + public void setDefaultFontInfo(FontInfo fontInfo) { + FontInfo fi = Java2DUtil.buildDefaultJava2DBasedFontInfo(fontInfo, getUserAgent()); + setFontInfo(fi); + } + + /** {@inheritDoc} */ + public IFDocumentHandlerConfigurator getConfigurator() { + return null; //No configurator, yet. + } + + /** {@inheritDoc} */ + public void startDocumentHeader() throws IFException { + try { + handler.startElement("defs"); + } catch (SAXException e) { + throw new IFException("SAX error in startDocumentHeader()", e); + } + } + + /** {@inheritDoc} */ + public void endDocumentHeader() throws IFException { + try { + handler.endElement("defs"); + } catch (SAXException e) { + throw new IFException("SAX error in startDocumentHeader()", e); + } + } + + /** {@inheritDoc} */ + public void handleExtensionObject(Object extension) throws IFException { + if (extension instanceof Metadata) { + Metadata meta = (Metadata)extension; + try { + handler.startElement("metadata"); + meta.toSAX(this.handler); + handler.endElement("metadata"); + } catch (SAXException e) { + throw new IFException("SAX error while handling extension object", e); + } + } else { + log.debug("Don't know how to handle extension object. Ignoring: " + + extension + " (" + extension.getClass().getName() + ")"); + } + } +} diff --git a/src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java b/src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java deleted file mode 100644 index 8f0be026e..000000000 --- a/src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.svg; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Paint; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Map; - -import org.w3c.dom.Document; - -import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.image.loader.ImageException; -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; -import org.apache.xmlgraphics.util.MimeConstants; -import org.apache.xmlgraphics.util.QName; -import org.apache.xmlgraphics.xmp.Metadata; - -import org.apache.fop.events.ResourceEventProducer; -import org.apache.fop.fo.extensions.ExtensionElementMapping; -import org.apache.fop.render.RenderingContext; -import org.apache.fop.render.intermediate.AbstractXMLWritingIFPainter; -import org.apache.fop.render.intermediate.IFConstants; -import org.apache.fop.render.intermediate.IFException; -import org.apache.fop.render.intermediate.IFState; -import org.apache.fop.traits.BorderProps; -import org.apache.fop.traits.RuleStyle; -import org.apache.fop.util.ColorUtil; - -/** - * Abstract base class for SVG Painter implementations. - */ -public abstract class AbstractSVGPainter extends AbstractXMLWritingIFPainter - implements SVGConstants { - - /** logging instance */ - private static Log log = LogFactory.getLog(AbstractSVGPainter.class); - - /** Holds the intermediate format state */ - protected IFState state; - - private static final int MODE_NORMAL = 0; - private static final int MODE_TEXT = 1; - - private int mode = MODE_NORMAL; - - /** {@inheritDoc} */ - protected String getMainNamespace() { - return NAMESPACE; - } - - /** {@inheritDoc} */ - public void startDocumentHeader() throws IFException { - try { - startElement("defs"); - } catch (SAXException e) { - throw new IFException("SAX error in startDocumentHeader()", e); - } - } - - /** {@inheritDoc} */ - public void endDocumentHeader() throws IFException { - try { - endElement("defs"); - } catch (SAXException e) { - throw new IFException("SAX error in startDocumentHeader()", e); - } - } - - /** {@inheritDoc} */ - public void startPageContent() throws IFException { - this.state = IFState.create(); - } - - /** {@inheritDoc} */ - public void endPageContent() throws IFException { - assert this.state.pop() == null; - } - - /** {@inheritDoc} */ - public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect) - throws IFException { - startViewport(toString(transform), size, clipRect); - } - - /** {@inheritDoc} */ - public void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect) - throws IFException { - startViewport(toString(transforms), size, clipRect); - } - - private void startViewport(String transform, Dimension size, Rectangle clipRect) - throws IFException { - try { - establish(MODE_NORMAL); - AttributesImpl atts = new AttributesImpl(); - if (transform != null && transform.length() > 0) { - atts.addAttribute("", "transform", "transform", CDATA, transform); - } - startElement("g", atts); - - atts.clear(); - atts.addAttribute("", "width", "width", CDATA, Integer.toString(size.width)); - atts.addAttribute("", "height", "height", CDATA, Integer.toString(size.height)); - if (clipRect != null) { - int[] v = new int[] { - clipRect.y, - -clipRect.x + size.width - clipRect.width, - -clipRect.y + size.height - clipRect.height, - clipRect.x}; - int sum = 0; - for (int i = 0; i < 4; i++) { - sum += Math.abs(v[i]); - } - if (sum != 0) { - StringBuffer sb = new StringBuffer("rect("); - sb.append(v[0]).append(','); - sb.append(v[1]).append(','); - sb.append(v[2]).append(','); - sb.append(v[3]).append(')'); - atts.addAttribute("", "clip", "clip", CDATA, sb.toString()); - } - atts.addAttribute("", "overflow", "overflow", CDATA, "hidden"); - } else { - atts.addAttribute("", "overflow", "overflow", CDATA, "visible"); - } - startElement("svg", atts); - } catch (SAXException e) { - throw new IFException("SAX error in startBox()", e); - } - } - - /** {@inheritDoc} */ - public void endViewport() throws IFException { - try { - establish(MODE_NORMAL); - endElement("svg"); - endElement("g"); - } catch (SAXException e) { - throw new IFException("SAX error in endBox()", e); - } - } - - /** {@inheritDoc} */ - public void startGroup(AffineTransform[] transforms) throws IFException { - startGroup(toString(transforms)); - } - - /** {@inheritDoc} */ - public void startGroup(AffineTransform transform) throws IFException { - startGroup(toString(transform)); - } - - private void startGroup(String transform) throws IFException { - try { - AttributesImpl atts = new AttributesImpl(); - if (transform != null && transform.length() > 0) { - atts.addAttribute("", "transform", "transform", CDATA, transform); - } - startElement("g", atts); - } catch (SAXException e) { - throw new IFException("SAX error in startGroup()", e); - } - } - - /** {@inheritDoc} */ - public void endGroup() throws IFException { - try { - establish(MODE_NORMAL); - endElement("g"); - } catch (SAXException e) { - throw new IFException("SAX error in endGroup()", e); - } - } - - private static final QName CONVERSION_MODE - = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); - - /** {@inheritDoc} */ - public void drawImage(String uri, Rectangle rect, Map foreignAttributes) throws IFException { - try { - establish(MODE_NORMAL); - - ImageManager manager = getUserAgent().getFactory().getImageManager(); - ImageInfo info = null; - try { - ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); - info = manager.getImageInfo(uri, sessionContext); - - String mime = info.getMimeType(); - String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE); - if ("reference".equals(conversionMode) - && (MimeConstants.MIME_GIF.equals(mime) - || MimeConstants.MIME_JPEG.equals(mime) - || MimeConstants.MIME_PNG.equals(mime) - || MimeConstants.MIME_SVG.equals(mime))) { - //Just reference the image - //TODO Some additional URI rewriting might be necessary - AttributesImpl atts = new AttributesImpl(); - addAttribute(atts, IFConstants.XLINK_HREF, uri); - atts.addAttribute("", "x", "x", CDATA, Integer.toString(rect.x)); - atts.addAttribute("", "y", "y", CDATA, Integer.toString(rect.y)); - atts.addAttribute("", "width", "width", CDATA, Integer.toString(rect.width)); - atts.addAttribute("", "height", "height", CDATA, Integer.toString(rect.height)); - element("image", atts); - } else { - drawImageUsingImageHandler(info, rect); - } - } catch (ImageException ie) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); - } catch (FileNotFoundException fe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); - } - } catch (SAXException e) { - throw new IFException("SAX error in drawImage()", e); - } - } - - /** {@inheritDoc} */ - public void drawImage(Document doc, Rectangle rect, Map foreignAttributes) throws IFException { - try { - establish(MODE_NORMAL); - - drawImageUsingDocument(doc, rect); - } catch (SAXException e) { - throw new IFException("SAX error in drawImage()", e); - } - } - - /** {@inheritDoc} */ - protected RenderingContext createRenderingContext() { - SVGRenderingContext svgContext = new SVGRenderingContext( - getUserAgent(), handler); - return svgContext; - } - - private static String toString(Paint paint) { - //TODO Paint serialization: Fine-tune and extend! - if (paint instanceof Color) { - return ColorUtil.colorToString((Color)paint); - } else { - throw new UnsupportedOperationException("Paint not supported: " + paint); - } - } - - /** {@inheritDoc} */ - public void clipRect(Rectangle rect) throws IFException { - //TODO Implement me!!! - } - - /** {@inheritDoc} */ - public void fillRect(Rectangle rect, Paint fill) throws IFException { - if (fill == null) { - return; - } - try { - establish(MODE_NORMAL); - AttributesImpl atts = new AttributesImpl(); - atts.addAttribute("", "x", "x", CDATA, Integer.toString(rect.x)); - atts.addAttribute("", "y", "y", CDATA, Integer.toString(rect.y)); - atts.addAttribute("", "width", "width", CDATA, Integer.toString(rect.width)); - atts.addAttribute("", "height", "height", CDATA, Integer.toString(rect.height)); - if (fill != null) { - atts.addAttribute("", "fill", "fill", CDATA, toString(fill)); - } - /* disabled - if (stroke != null) { - atts.addAttribute("", "stroke", "stroke", CDATA, toString(stroke)); - }*/ - element("rect", atts); - } catch (SAXException e) { - throw new IFException("SAX error in fillRect()", e); - } - } - - /** {@inheritDoc} */ - public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after, - BorderProps start, BorderProps end) throws IFException { - // TODO Auto-generated method stub - } - - /** {@inheritDoc} */ - public void drawLine(Point start, Point end, int width, Color color, RuleStyle style) - throws IFException { - try { - establish(MODE_NORMAL); - AttributesImpl atts = new AttributesImpl(); - atts.addAttribute("", "x1", "x1", CDATA, Integer.toString(start.x)); - atts.addAttribute("", "y1", "y1", CDATA, Integer.toString(start.y)); - atts.addAttribute("", "x2", "x2", CDATA, Integer.toString(end.x)); - atts.addAttribute("", "y2", "y2", CDATA, Integer.toString(end.y)); - atts.addAttribute("", "stroke-width", "stroke-width", CDATA, toString(color)); - atts.addAttribute("", "fill", "fill", CDATA, toString(color)); - //TODO Handle style parameter - element("line", atts); - } catch (SAXException e) { - throw new IFException("SAX error in drawLine()", e); - } - } - - /** {@inheritDoc} */ - public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException { - try { - establish(MODE_TEXT); - AttributesImpl atts = new AttributesImpl(); - atts.addAttribute("", "x", "x", CDATA, Integer.toString(x)); - atts.addAttribute("", "y", "y", CDATA, Integer.toString(y)); - if (dx != null) { - atts.addAttribute("", "dx", "dx", CDATA, toString(dx)); - } - if (dy != null) { - atts.addAttribute("", "dy", "dy", CDATA, toString(dy)); - } - startElement("text", atts); - char[] chars = text.toCharArray(); - handler.characters(chars, 0, chars.length); - endElement("text"); - } catch (SAXException e) { - throw new IFException("SAX error in setFont()", e); - } - } - - /** {@inheritDoc} */ - public void setFont(String family, String style, Integer weight, String variant, Integer size, - Color color) throws IFException { - if (family != null) { - state.setFontFamily(family); - } - if (style != null) { - state.setFontStyle(style); - } - if (weight != null) { - state.setFontWeight(weight.intValue()); - } - if (variant != null) { - state.setFontVariant(variant); - } - if (size != null) { - state.setFontSize(size.intValue()); - } - if (color != null) { - state.setTextColor(color); - } - } - - private void leaveTextMode() throws SAXException { - assert this.mode == MODE_TEXT; - endElement("g"); - this.mode = MODE_NORMAL; - } - - private void establish(int newMode) throws SAXException { - switch (newMode) { - case MODE_TEXT: - enterTextMode(); - break; - default: - if (this.mode == MODE_TEXT) { - leaveTextMode(); - } - } - } - - private void enterTextMode() throws SAXException { - if (state.isFontChanged() && this.mode == MODE_TEXT) { - leaveTextMode(); - } - if (this.mode != MODE_TEXT) { - startTextGroup(); - this.mode = MODE_TEXT; - } - } - - private void startTextGroup() throws SAXException { - AttributesImpl atts = new AttributesImpl(); - atts.addAttribute("", "font-family", "font-family", - CDATA, state.getFontFamily()); - atts.addAttribute("", "font-style", "font-style", - CDATA, state.getFontStyle()); - atts.addAttribute("", "font-weight", "font-weight", - CDATA, Integer.toString(state.getFontWeight())); - atts.addAttribute("", "font-variant", "font-variant", - CDATA, state.getFontVariant()); - atts.addAttribute("", "font-size", "font-size", - CDATA, Integer.toString(state.getFontSize())); - atts.addAttribute("", "fill", "fill", - CDATA, toString(state.getTextColor())); - startElement("g", atts); - state.resetFontChanged(); - } - - /** {@inheritDoc} */ - public void handleExtensionObject(Object extension) throws IFException { - if (extension instanceof Metadata) { - Metadata meta = (Metadata)extension; - try { - establish(MODE_NORMAL); - startElement("metadata"); - meta.toSAX(this.handler); - endElement("metadata"); - } catch (SAXException e) { - throw new IFException("SAX error while handling extension object", e); - } - } else { - throw new UnsupportedOperationException( - "Don't know how to handle extension object: " + extension); - } - } -} diff --git a/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java new file mode 100644 index 000000000..bd3dbc4e1 --- /dev/null +++ b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java @@ -0,0 +1,272 @@ +/* + * 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.svg; + +import java.awt.Dimension; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Result; +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.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; + +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.apache.commons.io.IOUtils; + +import org.apache.fop.render.bitmap.MultiFileRenderingUtil; +import org.apache.fop.render.intermediate.DelegatingFragmentContentHandler; +import org.apache.fop.render.intermediate.IFException; +import org.apache.fop.render.intermediate.IFPainter; +import org.apache.fop.util.GenerationHelperContentHandler; +import org.apache.fop.util.XMLUtil; + +/** + * {@code IFDocumentHandler} implementation that writes SVG 1.1. + */ +public class SVGDocumentHandler extends AbstractSVGDocumentHandler { + + /** Helper class for generating multiple files */ + private MultiFileRenderingUtil multiFileUtil; + + private StreamResult firstStream; + private StreamResult currentStream; + + private Document reusedParts; + + /** + * Default constructor. + */ + public SVGDocumentHandler() { + //nop + } + + /** {@inheritDoc} */ + public boolean supportsPagesOutOfOrder() { + return true; + } + + /** {@inheritDoc} */ + public String getMimeType() { + return MIME_TYPE; + } + + /** {@inheritDoc} */ + public void setResult(Result result) throws IFException { + if (result instanceof StreamResult) { + multiFileUtil = new MultiFileRenderingUtil(FILE_EXTENSION_SVG, + getUserAgent().getOutputFile()); + this.firstStream = (StreamResult)result; + } else { + throw new UnsupportedOperationException("Result is not supported: " + result); + } + } + + /** {@inheritDoc} */ + public void startDocument() throws IFException { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + builderFactory.setNamespaceAware(true); + builderFactory.setValidating(false); + try { + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + this.reusedParts = builder.newDocument(); + } catch (ParserConfigurationException e) { + throw new IFException("Error while setting up a DOM for SVG generation", e); + } + + try { + TransformerHandler toDOMHandler = tFactory.newTransformerHandler(); + toDOMHandler.setResult(new DOMResult(this.reusedParts)); + this.handler = decorate(toDOMHandler); + this.handler.startDocument(); + } catch (SAXException se) { + throw new IFException("SAX error in startDocument()", se); + } catch (TransformerConfigurationException e) { + throw new IFException( + "Error while setting up a TransformerHandler for SVG generation", e); + } + } + + /** {@inheritDoc} */ + public void endDocument() throws IFException { + //nop + } + + /** {@inheritDoc} */ + public void endDocumentHeader() throws IFException { + super.endDocumentHeader(); + try { + //Stop recording parts reused for each page + this.handler.endDocument(); + this.handler = null; + } catch (SAXException e) { + throw new IFException("SAX error in endDocumentHeader()", e); + } + } + + /** {@inheritDoc} */ + public void startPageSequence(String id) throws IFException { + //nop + } + + /** {@inheritDoc} */ + public void endPageSequence() throws IFException { + //nop + } + + /** {@inheritDoc} */ + public void startPage(int index, String name, Dimension size) throws IFException { + OutputStream out; + try { + if (index == 0) { + out = null; + } else { + out = this.multiFileUtil.createOutputStream(index); + if (out == null) { + //TODO Convert to event + throw new IFException( + "No filename information available. Stopping after first page.", null); + } + } + } catch (IOException ioe) { + throw new IFException("I/O exception while setting up output file", ioe); + } + if (out == null) { + this.handler = decorate(createContentHandler(this.firstStream)); + } else { + this.currentStream = new StreamResult(out); + this.handler = decorate(createContentHandler(this.currentStream)); + } + if (false) { + final ContentHandler originalHandler = this.handler; + this.handler = decorate((ContentHandler)Proxy.newProxyInstance( + ContentHandler.class.getClassLoader(), + new Class[] {ContentHandler.class}, + new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + String methodName = method.getName(); + System.out.println(methodName + ":"); + if (args != null) { + for (int i = 0; i < args.length; i++) { + System.out.println(" " + args[i]); + } + } + return method.invoke(originalHandler, args); + } + })); + } + try { + handler.startDocument(); + handler.startPrefixMapping("", NAMESPACE); + handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE); + AttributesImpl atts = new AttributesImpl(); + XMLUtil.addAttribute(atts, "version", "1.1"); //SVG 1.1 + /* + XMLUtil.addAttribute(atts, "index", Integer.toString(index)); + XMLUtil.addAttribute(atts, "name", name); + */ + XMLUtil.addAttribute(atts, "width", Float.toString(size.width / 1000f) + "pt"); + XMLUtil.addAttribute(atts, "height", Float.toString(size.height / 1000f) + "pt"); + XMLUtil.addAttribute(atts, "viewBox", + "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height)); + handler.startElement("svg", atts); + + try { + Transformer transformer = tFactory.newTransformer(); + Source src = new DOMSource(this.reusedParts.getDocumentElement()); + Result res = new SAXResult(new DelegatingFragmentContentHandler(this.handler)); + transformer.transform(src, res); + } catch (TransformerConfigurationException tce) { + throw new IFException("Error setting up a Transformer", tce); + } catch (TransformerException te) { + if (te.getCause() instanceof SAXException) { + throw (SAXException)te.getCause(); + } else { + throw new IFException("Error while serializing reused parts", te); + } + } + } catch (SAXException e) { + throw new IFException("SAX error in startPage()", e); + } + } + + private GenerationHelperContentHandler decorate(ContentHandler contentHandler) { + return new GenerationHelperContentHandler(contentHandler, getMainNamespace()); + } + + private void closeCurrentStream() { + if (this.currentStream != null) { + IOUtils.closeQuietly(currentStream.getOutputStream()); + currentStream.setOutputStream(null); + IOUtils.closeQuietly(currentStream.getWriter()); + currentStream.setWriter(null); + this.currentStream = null; + } + } + + /** {@inheritDoc} */ + public IFPainter startPageContent() throws IFException { + try { + handler.startElement("g"); + } catch (SAXException e) { + throw new IFException("SAX error in startPageContent()", e); + } + return new SVGPainter(this, handler); + } + + /** {@inheritDoc} */ + public void endPageContent() throws IFException { + try { + handler.endElement("g"); + } catch (SAXException e) { + throw new IFException("SAX error in endPageContent()", e); + } + } + + /** {@inheritDoc} */ + public void endPage() throws IFException { + try { + handler.endElement("svg"); + this.handler.endDocument(); + } catch (SAXException e) { + throw new IFException("SAX error in endPage()", e); + } + closeCurrentStream(); + } + +} diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPainterMaker.java b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java index a25a2f3b7..0296135fd 100644 --- a/src/sandbox/org/apache/fop/render/svg/SVGPainterMaker.java +++ b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java @@ -20,20 +20,22 @@ package org.apache.fop.render.svg; import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.render.intermediate.AbstractIFPainterMaker; -import org.apache.fop.render.intermediate.IFPainter; -import org.apache.fop.render.intermediate.IFPainterConfigurator; +import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker; +import org.apache.fop.render.intermediate.IFDocumentHandler; +import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator; /** - * Painter factory for SVG output. + * Document handler factory for SVG output. */ -public class SVGPainterMaker extends AbstractIFPainterMaker { +public class SVGDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker { private static final String[] MIMES = new String[] {SVGConstants.MIME_TYPE}; /** {@inheritDoc} */ - public IFPainter makePainter(FOUserAgent ua) { - return new SVGPainter(); + public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) { + SVGDocumentHandler handler = new SVGDocumentHandler(); + handler.setUserAgent(ua); + return handler; } /** {@inheritDoc} */ @@ -47,8 +49,7 @@ public class SVGPainterMaker extends AbstractIFPainterMaker { } /** {@inheritDoc} */ - public IFPainterConfigurator getConfigurator(FOUserAgent userAgent) { - // TODO Auto-generated method stub + public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) { return null; } diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPainter.java b/src/sandbox/org/apache/fop/render/svg/SVGPainter.java index aa52673a9..e0d12d9c7 100644 --- a/src/sandbox/org/apache/fop/render/svg/SVGPainter.java +++ b/src/sandbox/org/apache/fop/render/svg/SVGPainter.java @@ -19,250 +19,416 @@ package org.apache.fop.render.svg; +import java.awt.Color; import java.awt.Dimension; +import java.awt.Paint; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.io.FileNotFoundException; import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -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.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; +import java.util.Map; import org.w3c.dom.Document; -import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; -import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; -import org.apache.fop.render.bitmap.MultiFileRenderingUtil; -import org.apache.fop.render.intermediate.DelegatingFragmentContentHandler; +import org.apache.xmlgraphics.image.loader.ImageException; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.apache.xmlgraphics.image.loader.ImageSessionContext; +import org.apache.xmlgraphics.util.QName; +import org.apache.xmlgraphics.xmp.Metadata; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.events.ResourceEventProducer; +import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.render.RenderingContext; +import org.apache.fop.render.intermediate.AbstractIFPainter; +import org.apache.fop.render.intermediate.IFConstants; import org.apache.fop.render.intermediate.IFException; +import org.apache.fop.render.intermediate.IFState; +import org.apache.fop.render.intermediate.IFUtil; +import org.apache.fop.traits.BorderProps; +import org.apache.fop.traits.RuleStyle; +import org.apache.fop.util.ColorUtil; +import org.apache.fop.util.GenerationHelperContentHandler; +import org.apache.fop.util.XMLUtil; /** * IFPainter implementation that writes SVG. */ -public class SVGPainter extends AbstractSVGPainter { +public class SVGPainter extends AbstractIFPainter implements SVGConstants { + + /** logging instance */ + private static Log log = LogFactory.getLog(SVGPainter.class); + + /** Holds the intermediate format state */ + protected IFState state; - /** Helper class for generating multiple files */ - private MultiFileRenderingUtil multiFileUtil; + private AbstractSVGDocumentHandler parent; - private StreamResult firstStream; - private StreamResult currentStream; + /** The SAX content handler that receives the generated XML events. */ + protected GenerationHelperContentHandler handler; - private Document reusedParts; + private static final int MODE_NORMAL = 0; + private static final int MODE_TEXT = 1; + + private int mode = MODE_NORMAL; /** - * Default constructor. + * Main constructor. + * @param parent the parent document handler + * @param contentHandler the target SAX content handler */ - public SVGPainter() { - //nop + public SVGPainter(AbstractSVGDocumentHandler parent, + GenerationHelperContentHandler contentHandler) { + super(); + this.parent = parent; + this.handler = contentHandler; + this.state = IFState.create(); } /** {@inheritDoc} */ - public boolean supportsPagesOutOfOrder() { - return true; + protected FOUserAgent getUserAgent() { + return parent.getUserAgent(); } /** {@inheritDoc} */ - public String getMimeType() { - return MIME_TYPE; + public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect) + throws IFException { + startViewport(IFUtil.toString(transform), size, clipRect); } /** {@inheritDoc} */ - public void setResult(Result result) throws IFException { - if (result instanceof StreamResult) { - multiFileUtil = new MultiFileRenderingUtil(FILE_EXTENSION_SVG, - getUserAgent().getOutputFile()); - this.firstStream = (StreamResult)result; - } else { - throw new UnsupportedOperationException("Result is not supported: " + result); - } + public void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect) + throws IFException { + startViewport(IFUtil.toString(transforms), size, clipRect); } - /** {@inheritDoc} */ - public void startDocument() throws IFException { - DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); - builderFactory.setNamespaceAware(true); - builderFactory.setValidating(false); + private void startViewport(String transform, Dimension size, Rectangle clipRect) + throws IFException { try { - DocumentBuilder builder = builderFactory.newDocumentBuilder(); - this.reusedParts = builder.newDocument(); - } catch (ParserConfigurationException e) { - throw new IFException("Error while setting up a DOM for SVG generation", e); + establish(MODE_NORMAL); + AttributesImpl atts = new AttributesImpl(); + if (transform != null && transform.length() > 0) { + XMLUtil.addAttribute(atts, "transform", transform); + } + handler.startElement("g", atts); + + atts.clear(); + XMLUtil.addAttribute(atts, "width", Integer.toString(size.width)); + XMLUtil.addAttribute(atts, "height", Integer.toString(size.height)); + if (clipRect != null) { + int[] v = new int[] { + clipRect.y, + -clipRect.x + size.width - clipRect.width, + -clipRect.y + size.height - clipRect.height, + clipRect.x}; + int sum = 0; + for (int i = 0; i < 4; i++) { + sum += Math.abs(v[i]); + } + if (sum != 0) { + StringBuffer sb = new StringBuffer("rect("); + sb.append(v[0]).append(','); + sb.append(v[1]).append(','); + sb.append(v[2]).append(','); + sb.append(v[3]).append(')'); + XMLUtil.addAttribute(atts, "clip", sb.toString()); + } + XMLUtil.addAttribute(atts, "overflow", "hidden"); + } else { + XMLUtil.addAttribute(atts, "overflow", "visible"); + } + handler.startElement("svg", atts); + } catch (SAXException e) { + throw new IFException("SAX error in startBox()", e); } + } + /** {@inheritDoc} */ + public void endViewport() throws IFException { try { - TransformerHandler toDOMHandler = tFactory.newTransformerHandler(); - toDOMHandler.setResult(new DOMResult(this.reusedParts)); - this.handler = toDOMHandler; - this.handler.startDocument(); - } catch (SAXException se) { - throw new IFException("SAX error in startDocument()", se); - } catch (TransformerConfigurationException e) { - throw new IFException( - "Error while setting up a TransformerHandler for SVG generation", e); + establish(MODE_NORMAL); + handler.endElement("svg"); + handler.endElement("g"); + } catch (SAXException e) { + throw new IFException("SAX error in endBox()", e); } } /** {@inheritDoc} */ - public void endDocument() throws IFException { - //nop + public void startGroup(AffineTransform[] transforms) throws IFException { + startGroup(IFUtil.toString(transforms)); } /** {@inheritDoc} */ - public void endDocumentHeader() throws IFException { - super.endDocumentHeader(); + public void startGroup(AffineTransform transform) throws IFException { + startGroup(IFUtil.toString(transform)); + } + + private void startGroup(String transform) throws IFException { try { - //Stop recording parts reused for each page - this.handler.endDocument(); - this.handler = null; + AttributesImpl atts = new AttributesImpl(); + if (transform != null && transform.length() > 0) { + XMLUtil.addAttribute(atts, "transform", transform); + } + handler.startElement("g", atts); } catch (SAXException e) { - throw new IFException("SAX error in endDocumentHeader()", e); + throw new IFException("SAX error in startGroup()", e); } } /** {@inheritDoc} */ - public void startPageSequence(String id) throws IFException { - //nop + public void endGroup() throws IFException { + try { + establish(MODE_NORMAL); + handler.endElement("g"); + } catch (SAXException e) { + throw new IFException("SAX error in endGroup()", e); + } } - /** {@inheritDoc} */ - public void endPageSequence() throws IFException { - //nop - } + private static final QName CONVERSION_MODE + = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); /** {@inheritDoc} */ - public void startPage(int index, String name, Dimension size) throws IFException { - OutputStream out; + public void drawImage(String uri, Rectangle rect, Map foreignAttributes) throws IFException { try { - if (index == 0) { - out = null; - } else { - out = this.multiFileUtil.createOutputStream(index); - if (out == null) { - //TODO Convert to event - throw new IFException( - "No filename information available. Stopping after first page.", null); + establish(MODE_NORMAL); + + ImageManager manager = getUserAgent().getFactory().getImageManager(); + ImageInfo info = null; + try { + ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); + info = manager.getImageInfo(uri, sessionContext); + + String mime = info.getMimeType(); + String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE); + if ("reference".equals(conversionMode) + && (MimeConstants.MIME_GIF.equals(mime) + || MimeConstants.MIME_JPEG.equals(mime) + || MimeConstants.MIME_PNG.equals(mime) + || MimeConstants.MIME_SVG.equals(mime))) { + //Just reference the image + //TODO Some additional URI rewriting might be necessary + AttributesImpl atts = new AttributesImpl(); + XMLUtil.addAttribute(atts, IFConstants.XLINK_HREF, uri); + XMLUtil.addAttribute(atts, "x", Integer.toString(rect.x)); + XMLUtil.addAttribute(atts, "y", Integer.toString(rect.y)); + XMLUtil.addAttribute(atts, "width", Integer.toString(rect.width)); + XMLUtil.addAttribute(atts, "height", Integer.toString(rect.height)); + handler.element("image", atts); + } else { + drawImageUsingImageHandler(info, rect); } + } catch (ImageException ie) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); + } catch (FileNotFoundException fe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); + } catch (IOException ioe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); } - } catch (IOException ioe) { - throw new IFException("I/O exception while setting up output file", ioe); + } catch (SAXException e) { + throw new IFException("SAX error in drawImage()", e); } - if (out == null) { - this.handler = createContentHandler(this.firstStream); + } + + /** {@inheritDoc} */ + public void drawImage(Document doc, Rectangle rect, Map foreignAttributes) throws IFException { + try { + establish(MODE_NORMAL); + + drawImageUsingDocument(doc, rect); + } catch (SAXException e) { + throw new IFException("SAX error in drawImage()", e); + } + } + + /** {@inheritDoc} */ + protected RenderingContext createRenderingContext() { + SVGRenderingContext svgContext = new SVGRenderingContext( + getUserAgent(), handler); + return svgContext; + } + + private static String toString(Paint paint) { + //TODO Paint serialization: Fine-tune and extend! + if (paint instanceof Color) { + return ColorUtil.colorToString((Color)paint); } else { - this.currentStream = new StreamResult(out); - this.handler = createContentHandler(this.currentStream); + throw new UnsupportedOperationException("Paint not supported: " + paint); } - if (false) { - final ContentHandler originalHandler = this.handler; - this.handler = (ContentHandler)Proxy.newProxyInstance( - ContentHandler.class.getClassLoader(), - new Class[] {ContentHandler.class}, - new InvocationHandler() { - public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable { - String methodName = method.getName(); - System.out.println(methodName + ":"); - if (args != null) { - for (int i = 0; i < args.length; i++) { - System.out.println(" " + args[i]); - } - } - return method.invoke(originalHandler, args); - } - }); + } + + /** {@inheritDoc} */ + public void clipRect(Rectangle rect) throws IFException { + //TODO Implement me!!! + } + + /** {@inheritDoc} */ + public void fillRect(Rectangle rect, Paint fill) throws IFException { + if (fill == null) { + return; } try { - handler.startDocument(); - handler.startPrefixMapping("", NAMESPACE); - handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE); + establish(MODE_NORMAL); AttributesImpl atts = new AttributesImpl(); - atts.addAttribute("", "version", "version", CDATA, "1.1"); //SVG 1.1 - /* - atts.addAttribute("", "index", "index", CDATA, Integer.toString(index)); - atts.addAttribute("", "name", "name", CDATA, name); - */ - atts.addAttribute("", "width", "width", CDATA, - Float.toString(size.width / 1000f) + "pt"); - atts.addAttribute("", "height", "height", CDATA, - Float.toString(size.height / 1000f) + "pt"); - atts.addAttribute("", "viewBox", "viewBox", CDATA, - "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height)); - startElement("svg", atts); - - try { - Transformer transformer = tFactory.newTransformer(); - Source src = new DOMSource(this.reusedParts.getDocumentElement()); - Result res = new SAXResult(new DelegatingFragmentContentHandler(this.handler)); - transformer.transform(src, res); - } catch (TransformerConfigurationException tce) { - throw new IFException("Error setting up a Transformer", tce); - } catch (TransformerException te) { - if (te.getCause() instanceof SAXException) { - throw (SAXException)te.getCause(); - } else { - throw new IFException("Error while serializing reused parts", te); - } + XMLUtil.addAttribute(atts, "x", Integer.toString(rect.x)); + XMLUtil.addAttribute(atts, "y", Integer.toString(rect.y)); + XMLUtil.addAttribute(atts, "width", Integer.toString(rect.width)); + XMLUtil.addAttribute(atts, "height", Integer.toString(rect.height)); + if (fill != null) { + XMLUtil.addAttribute(atts, "fill", toString(fill)); } + /* disabled + if (stroke != null) { + XMLUtil.addAttribute(atts, "stroke", toString(stroke)); + }*/ + handler.element("rect", atts); } catch (SAXException e) { - throw new IFException("SAX error in startPage()", e); + throw new IFException("SAX error in fillRect()", e); } } - private void closeCurrentStream() { - if (this.currentStream != null) { - IOUtils.closeQuietly(currentStream.getOutputStream()); - currentStream.setOutputStream(null); - IOUtils.closeQuietly(currentStream.getWriter()); - currentStream.setWriter(null); - this.currentStream = null; - } + /** {@inheritDoc} */ + public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after, + BorderProps start, BorderProps end) throws IFException { + // TODO Auto-generated method stub } /** {@inheritDoc} */ - public void startPageContent() throws IFException { - super.startPageContent(); + public void drawLine(Point start, Point end, int width, Color color, RuleStyle style) + throws IFException { try { - startElement("g"); + establish(MODE_NORMAL); + AttributesImpl atts = new AttributesImpl(); + XMLUtil.addAttribute(atts, "x1", Integer.toString(start.x)); + XMLUtil.addAttribute(atts, "y1", Integer.toString(start.y)); + XMLUtil.addAttribute(atts, "x2", Integer.toString(end.x)); + XMLUtil.addAttribute(atts, "y2", Integer.toString(end.y)); + XMLUtil.addAttribute(atts, "stroke-width", toString(color)); + XMLUtil.addAttribute(atts, "fill", toString(color)); + //TODO Handle style parameter + handler.element("line", atts); } catch (SAXException e) { - throw new IFException("SAX error in startPageContent()", e); + throw new IFException("SAX error in drawLine()", e); } } /** {@inheritDoc} */ - public void endPageContent() throws IFException { + public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException { try { - endElement("g"); + establish(MODE_TEXT); + AttributesImpl atts = new AttributesImpl(); + XMLUtil.addAttribute(atts, "x", Integer.toString(x)); + XMLUtil.addAttribute(atts, "y", Integer.toString(y)); + if (dx != null) { + XMLUtil.addAttribute(atts, "dx", IFUtil.toString(dx)); + } + if (dy != null) { + XMLUtil.addAttribute(atts, "dy", IFUtil.toString(dy)); + } + handler.startElement("text", atts); + char[] chars = text.toCharArray(); + handler.characters(chars, 0, chars.length); + handler.endElement("text"); } catch (SAXException e) { - throw new IFException("SAX error in endPageContent()", e); + throw new IFException("SAX error in setFont()", e); } - super.endPageContent(); } /** {@inheritDoc} */ - public void endPage() throws IFException { - try { - endElement("svg"); - this.handler.endDocument(); - } catch (SAXException e) { - throw new IFException("SAX error in endPage()", e); + public void setFont(String family, String style, Integer weight, String variant, Integer size, + Color color) throws IFException { + if (family != null) { + state.setFontFamily(family); + } + if (style != null) { + state.setFontStyle(style); + } + if (weight != null) { + state.setFontWeight(weight.intValue()); + } + if (variant != null) { + state.setFontVariant(variant); + } + if (size != null) { + state.setFontSize(size.intValue()); + } + if (color != null) { + state.setTextColor(color); + } + } + + private void leaveTextMode() throws SAXException { + assert this.mode == MODE_TEXT; + handler.endElement("g"); + this.mode = MODE_NORMAL; + } + + private void establish(int newMode) throws SAXException { + switch (newMode) { + case MODE_TEXT: + enterTextMode(); + break; + default: + if (this.mode == MODE_TEXT) { + leaveTextMode(); + } + } + } + + private void enterTextMode() throws SAXException { + if (state.isFontChanged() && this.mode == MODE_TEXT) { + leaveTextMode(); + } + if (this.mode != MODE_TEXT) { + startTextGroup(); + this.mode = MODE_TEXT; + } + } + + private void startTextGroup() throws SAXException { + AttributesImpl atts = new AttributesImpl(); + XMLUtil.addAttribute(atts, "font-family", state.getFontFamily()); + XMLUtil.addAttribute(atts, "font-style", state.getFontStyle()); + XMLUtil.addAttribute(atts, "font-weight", Integer.toString(state.getFontWeight())); + XMLUtil.addAttribute(atts, "font-variant", state.getFontVariant()); + XMLUtil.addAttribute(atts, "font-size", Integer.toString(state.getFontSize())); + XMLUtil.addAttribute(atts, "fill", toString(state.getTextColor())); + handler.startElement("g", atts); + state.resetFontChanged(); + } + + /** {@inheritDoc} */ + public void handleExtensionObject(Object extension) throws IFException { + if (extension instanceof Metadata) { + Metadata meta = (Metadata)extension; + try { + establish(MODE_NORMAL); + handler.startElement("metadata"); + meta.toSAX(this.handler); + handler.endElement("metadata"); + } catch (SAXException e) { + throw new IFException("SAX error while handling extension object", e); + } + } else { + throw new UnsupportedOperationException( + "Don't know how to handle extension object: " + extension); } - closeCurrentStream(); } } diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPrintPainter.java b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java index 7f5c84cef..ee69f95ae 100644 --- a/src/sandbox/org/apache/fop/render/svg/SVGPrintPainter.java +++ b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java @@ -28,16 +28,18 @@ import org.xml.sax.helpers.AttributesImpl; import org.apache.fop.render.intermediate.IFConstants; import org.apache.fop.render.intermediate.IFException; +import org.apache.fop.render.intermediate.IFPainter; +import org.apache.fop.util.XMLUtil; /** - * IFPainter implementation that writes SVG Print. + * {@code IFDocumentHandler} implementation that writes SVG Print. */ -public class SVGPrintPainter extends AbstractSVGPainter { +public class SVGPrintDocumentHandler extends AbstractSVGDocumentHandler { /** * Default constructor. */ - public SVGPrintPainter() { + public SVGPrintDocumentHandler() { //nop } @@ -47,7 +49,7 @@ public class SVGPrintPainter extends AbstractSVGPainter { * @param result the JAXP Result object to receive the generated content * @throws IFException if an error occurs setting up the output */ - public SVGPrintPainter(Result result) throws IFException { + public SVGPrintDocumentHandler(Result result) throws IFException { setResult(result); } @@ -69,8 +71,8 @@ public class SVGPrintPainter extends AbstractSVGPainter { handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE); handler.startPrefixMapping("if", IFConstants.NAMESPACE); AttributesImpl atts = new AttributesImpl(); - atts.addAttribute("", "version", "version", CDATA, "1.2"); //SVG Print is SVG 1.2 - startElement("svg", atts); + XMLUtil.addAttribute(atts, "version", "1.2"); //SVG Print is SVG 1.2 + handler.startElement("svg", atts); } catch (SAXException e) { throw new IFException("SAX error in startDocument()", e); } @@ -79,7 +81,7 @@ public class SVGPrintPainter extends AbstractSVGPainter { /** {@inheritDoc} */ public void endDocument() throws IFException { try { - endElement("svg"); + handler.endElement("svg"); handler.endDocument(); } catch (SAXException e) { throw new IFException("SAX error in endDocument()", e); @@ -93,7 +95,7 @@ public class SVGPrintPainter extends AbstractSVGPainter { if (id != null) { atts.addAttribute(XML_NAMESPACE, "id", "xml:id", CDATA, id); } - startElement("pageSet", atts); + handler.startElement("pageSet", atts); } catch (SAXException e) { throw new IFException("SAX error in startPageSequence()", e); } @@ -102,7 +104,7 @@ public class SVGPrintPainter extends AbstractSVGPainter { /** {@inheritDoc} */ public void endPageSequence() throws IFException { try { - endElement("pageSet"); + handler.endElement("pageSet"); } catch (SAXException e) { throw new IFException("SAX error in endPageSequence()", e); } @@ -113,8 +115,8 @@ public class SVGPrintPainter extends AbstractSVGPainter { try { AttributesImpl atts = new AttributesImpl(); /* - atts.addAttribute("", "index", "index", CDATA, Integer.toString(index)); - atts.addAttribute("", "name", "name", CDATA, name); + XMLUtil.addAttribute(atts, "index", Integer.toString(index)); + XMLUtil.addAttribute(atts, "name", name); */ //NOTE: SVG Print doesn't support individual page sizes for each page atts.addAttribute(IFConstants.NAMESPACE, "width", "if:width", @@ -123,7 +125,7 @@ public class SVGPrintPainter extends AbstractSVGPainter { CDATA, Integer.toString(size.height)); atts.addAttribute(IFConstants.NAMESPACE, "viewBox", "if:viewBox", CDATA, "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height)); - startElement("page", atts); + handler.startElement("page", atts); } catch (SAXException e) { throw new IFException("SAX error in startPage()", e); } @@ -138,23 +140,22 @@ public class SVGPrintPainter extends AbstractSVGPainter { } /** {@inheritDoc} */ - public void startPageContent() throws IFException { - super.startPageContent(); + public IFPainter startPageContent() throws IFException { try { - startElement("g"); + handler.startElement("g"); } catch (SAXException e) { throw new IFException("SAX error in startPageContent()", e); } + return new SVGPainter(this, handler); } /** {@inheritDoc} */ public void endPageContent() throws IFException { try { - endElement("g"); + handler.endElement("g"); } catch (SAXException e) { throw new IFException("SAX error in endPageContent()", e); } - super.endPageContent(); } /** {@inheritDoc} */ @@ -168,7 +169,7 @@ public class SVGPrintPainter extends AbstractSVGPainter { /** {@inheritDoc} */ public void endPage() throws IFException { try { - endElement("page"); + handler.endElement("page"); } catch (SAXException e) { throw new IFException("SAX error in endPage()", e); } diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPrintPainterMaker.java b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java index 55a7bf753..61993da13 100644 --- a/src/sandbox/org/apache/fop/render/svg/SVGPrintPainterMaker.java +++ b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java @@ -20,20 +20,22 @@ package org.apache.fop.render.svg; import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.render.intermediate.AbstractIFPainterMaker; -import org.apache.fop.render.intermediate.IFPainter; -import org.apache.fop.render.intermediate.IFPainterConfigurator; +import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker; +import org.apache.fop.render.intermediate.IFDocumentHandler; +import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator; /** - * Painter factory for SVG Print output. + * Document handler factory for SVG Print output. */ -public class SVGPrintPainterMaker extends AbstractIFPainterMaker { +public class SVGPrintDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker { private static final String[] MIMES = new String[] {SVGConstants.MIME_SVG_PRINT}; /** {@inheritDoc} */ - public IFPainter makePainter(FOUserAgent ua) { - return new SVGPrintPainter(); + public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) { + SVGPrintDocumentHandler handler = new SVGPrintDocumentHandler(); + handler.setUserAgent(ua); + return handler; } /** {@inheritDoc} */ @@ -47,8 +49,7 @@ public class SVGPrintPainterMaker extends AbstractIFPainterMaker { } /** {@inheritDoc} */ - public IFPainterConfigurator getConfigurator(FOUserAgent userAgent) { - // TODO Auto-generated method stub + public IFDocumentHandlerConfigurator getConfigurator(FOUserAgent userAgent) { return null; } |