From 8e94b3ad33854852846b6333e09e7cd38a2cc5e0 Mon Sep 17 00:00:00 2001 From: Adrian Cumiskey Date: Thu, 10 Jul 2008 16:21:36 +0000 Subject: [PATCH] Committing the beginnings of what I began prototyping sometime ago... not sure how useful it is going forward. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@675636 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/apps/MimeConstants.java | 3 +- .../apache/fop/cli/CommandLineOptions.java | 33 +- .../fop/render/iform/IFContentHandler.java | 89 ++++++ .../apache/fop/render/iform/IFPainter.java | 68 +++++ .../apache/fop/render/iform/IFRenderer.java | 289 ++++++++++++++++++ 5 files changed, 480 insertions(+), 2 deletions(-) create mode 100644 src/java/org/apache/fop/render/iform/IFContentHandler.java create mode 100644 src/java/org/apache/fop/render/iform/IFPainter.java create mode 100644 src/java/org/apache/fop/render/iform/IFRenderer.java diff --git a/src/java/org/apache/fop/apps/MimeConstants.java b/src/java/org/apache/fop/apps/MimeConstants.java index cdd30c0e1..418dc8524 100644 --- a/src/java/org/apache/fop/apps/MimeConstants.java +++ b/src/java/org/apache/fop/apps/MimeConstants.java @@ -73,7 +73,8 @@ public interface MimeConstants { String MIME_FOP_PRINT = "application/X-fop-print"; /** Apache FOP's area tree XML */ String MIME_FOP_AREA_TREE = "application/X-fop-areatree"; - + /** Apache FOP's intermediate format XML */ + String MIME_FOP_IF = "application/X-fop-intermediate-format"; /** Proposed but non-registered MIME type for XSL-FO */ String MIME_XSL_FO = "text/xsl"; diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java index 4e5c8ae44..ee2cba40c 100644 --- a/src/java/org/apache/fop/cli/CommandLineOptions.java +++ b/src/java/org/apache/fop/cli/CommandLineOptions.java @@ -45,6 +45,7 @@ import org.apache.fop.pdf.PDFEncryptionParams; import org.apache.fop.pdf.PDFXMode; import org.apache.fop.render.Renderer; import org.apache.fop.render.awt.AWTRenderer; +import org.apache.fop.render.iform.IFRenderer; import org.apache.fop.render.pdf.PDFRenderer; import org.apache.fop.render.print.PagesMode; import org.apache.fop.render.print.PrintRenderer; @@ -197,6 +198,13 @@ public class CommandLineOptions { //Make sure the prepared XMLRenderer is used foUserAgent.setRendererOverride(xmlRenderer); + } else if (MimeConstants.MIME_FOP_IF.equals(outputmode)) { + // render from FO to Intermediate Format + IFRenderer xml2Renderer = new IFRenderer(); + xml2Renderer.setUserAgent(foUserAgent); + + //Make sure the prepared IFRenderer is used + foUserAgent.setRendererOverride(xml2Renderer); } return true; } @@ -302,6 +310,8 @@ public class CommandLineOptions { i = i + parseUnknownOption(args, i); } else if (args[i].equals("-at")) { i = i + parseAreaTreeOption(args, i); + } else if (args[i].equals("-if")) { + i = i + parseIntermediateFormatOption(args, i); } else if (args[i].equals("-v")) { System.out.println("FOP Version " + Version.getVersion()); } else if (args[i].equals("-param")) { @@ -612,7 +622,7 @@ public class CommandLineOptions { if ((i + 1 == args.length) || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the area-tree output file"); - } else if ((i + 2 == args.length) + } else if ((i + 2 == args.length) || (args[i + 2].charAt(0) == '-')) { // only output file is specified outfile = new File(args[i + 1]); @@ -625,6 +635,23 @@ public class CommandLineOptions { } } + private int parseIntermediateFormatOption(String[] args, int i) throws FOPException { + setOutputMode(MimeConstants.MIME_FOP_IF); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the intermediate format output file"); + } else if ((i + 2 == args.length) + || (args[i + 2].charAt(0) == '-')) { + // only output file is specified + outfile = new File(args[i + 1]); + return 1; + } else { + // mimic format and output file have been specified + outfile = new File(args[i + 2]); + return 2; + } + } + private int parseAreaTreeInputOption(String[] args, int i) throws FOPException { inputmode = AREATREE_INPUT; if ((i + 1 == args.length) @@ -1009,6 +1036,7 @@ public class CommandLineOptions { + " -at [mime] out representation of area tree as XML (outfile req'd) \n" + " specify optional mime output to allow AT to be converted\n" + " to final format later\n" + + " -if out representation of area tree as intermediate format XML (outfile req'd)\n" + " -print input file will be rendered and sent to the printer \n" + " see options with \"-print help\" \n" + " -out mime outfile input will be rendered using the given MIME type\n" @@ -1088,6 +1116,9 @@ public class CommandLineOptions { log.info("mimic renderer: " + mimicRenderer); } log.info("output file: " + outfile.toString()); + } else if (MimeConstants.MIME_FOP_IF.equals(outputmode)) { + log.info("intermediate format"); + log.info("output file: " + outfile.toString()); } else { log.info(outputmode); log.info("output file: " + outfile.toString()); diff --git a/src/java/org/apache/fop/render/iform/IFContentHandler.java b/src/java/org/apache/fop/render/iform/IFContentHandler.java new file mode 100644 index 000000000..4c70c0d30 --- /dev/null +++ b/src/java/org/apache/fop/render/iform/IFContentHandler.java @@ -0,0 +1,89 @@ +/* + * 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.iform; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; + +public class IFContentHandler implements ContentHandler { + + public void characters(char[] arg0, int arg1, int arg2) throws SAXException { + // TODO Auto-generated method stub + + } + + public void endDocument() throws SAXException { + // TODO Auto-generated method stub + + } + + public void endElement(String arg0, String arg1, String arg2) + throws SAXException { + // TODO Auto-generated method stub + + } + + public void endPrefixMapping(String arg0) throws SAXException { + // TODO Auto-generated method stub + + } + + public void ignorableWhitespace(char[] arg0, int arg1, int arg2) + throws SAXException { + // TODO Auto-generated method stub + + } + + public void processingInstruction(String arg0, String arg1) + throws SAXException { + // TODO Auto-generated method stub + + } + + public void setDocumentLocator(Locator arg0) { + // TODO Auto-generated method stub + + } + + public void skippedEntity(String arg0) throws SAXException { + // TODO Auto-generated method stub + + } + + public void startDocument() throws SAXException { + // TODO Auto-generated method stub + + } + + public void startElement(String arg0, String arg1, String arg2, + Attributes arg3) throws SAXException { + // TODO Auto-generated method stub + + } + + public void startPrefixMapping(String arg0, String arg1) + throws SAXException { + // TODO Auto-generated method stub + + } + +} diff --git a/src/java/org/apache/fop/render/iform/IFPainter.java b/src/java/org/apache/fop/render/iform/IFPainter.java new file mode 100644 index 000000000..c648e8ebd --- /dev/null +++ b/src/java/org/apache/fop/render/iform/IFPainter.java @@ -0,0 +1,68 @@ +/* + * 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.iform; + +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; + +import org.xml.sax.ContentHandler; + +public interface IFPainter { + + //for foreign content and extensions + ContentHandler getContentHandler(); + + void startDocument(); + void endDocument(); + + void startDocumentHeader(); + void endDocumentHeader(); + + void startPageSequence(String id); + void endPageSequence(); + + void startPage(int index, String name); + void endPage(); + + void startPageHeader(); + void endPageHeader(); + + void startPageContent(); + void endPageContent(); + + void startPageTrailer(); + void addTarget(String name, int x, int y); + void endPageTrailer(); + + void startBox(AffineTransform transform, Dimension size, boolean clip); + void startBox(String transform, Dimension size, boolean clip); + //For transform, something like Batik's org.apache.batik.parser.TransformListHandler/Parser can be used + void endBox(); + + void setFont(String family, String style, Integer weight, String variant, Integer size, String color); + //All of setFont()'s parameters can be null if no state change is necessary + void drawText(int[] x, int[] y, String text); + void drawRect(Rectangle rect, String fill, String stroke); + void drawImage(String uri, Rectangle rect); //external images + void startImage(Rectangle rect); //followed by a SAX stream (SVG etc.) + void endImage(); + //etc. etc. +} diff --git a/src/java/org/apache/fop/render/iform/IFRenderer.java b/src/java/org/apache/fop/render/iform/IFRenderer.java new file mode 100644 index 000000000..3ff5a6f68 --- /dev/null +++ b/src/java/org/apache/fop/render/iform/IFRenderer.java @@ -0,0 +1,289 @@ +/* + * 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.iform; + +import java.awt.Color; +import java.awt.color.ColorSpace; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.BookmarkData; +import org.apache.fop.area.CTM; +import org.apache.fop.area.LineArea; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Trait; +import org.apache.fop.area.Trait.Background; +import org.apache.fop.area.inline.ForeignObject; +import org.apache.fop.area.inline.Image; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.SpaceArea; +import org.apache.fop.area.inline.TextArea; +import org.apache.fop.area.inline.WordArea; +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.render.RendererContext; +import org.apache.fop.render.xml.AbstractXMLRenderer; +import org.xml.sax.SAXException; + +public class IFRenderer extends AbstractXMLRenderer { + + /** logging instance */ + protected static Log log = LogFactory.getLog("IFRenderer"); + + /** XML MIME type */ + public static final String IF_MIME_TYPE = MimeConstants.MIME_FOP_IF; + private boolean pageSeqStarted = false; + + private String currentText; + + private Area parentArea; + + /** + * Main constructor + */ + public IFRenderer() { + context = new RendererContext(this, IF_MIME_TYPE); + } + + /** + * {@inheritDoc} + */ + public void startRenderer(OutputStream outputStream) + throws IOException { + log.debug("Rendering areas to intermediate format XML"); + super.startRenderer(outputStream); + if (userAgent.getProducer() != null) { + comment("Produced by " + userAgent.getProducer()); + } + startElement("document"); + startElement("content"); + startElement("svg"); + } + + /** {@inheritDoc} */ + public void startPageSequence(LineArea seqTitle) { + if (pageSeqStarted) { + endElement("pageSet"); + } + pageSeqStarted = true; + startElement("pageSet"); + } + + /** + * {@inheritDoc} + */ + public void stopRenderer() throws IOException { + if (pageSeqStarted) { + endElement("pageSet"); + } + endElement("svg"); + endElement("content"); + endElement("document"); + super.stopRenderer(); + log.debug("Written out intermediate format XML"); + } + +// /** +// * {@inheritDoc} +// */ +// protected void renderFlow(NormalFlow flow) { +// log.debug("renderFlow() " + flow); +// super.renderFlow(flow); +// } +// + /** + * {@inheritDoc} + */ + protected void renderBlock(Block block) { + log.debug("renderBlock() " + block); + addTraitAttributes(block); + startElement("g", atts); + this.parentArea = block; + super.renderBlock(block); + this.parentArea = null; + endElement("g"); + } + + /** + * Renders an fo:foreing-object. + * @param fo the foreign object + * @param pos the position of the foreign object + * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D) + */ + public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { + log.debug("renderForeignObject() fo=" + fo + ", pos=" + pos); + super.renderForeignObject(fo, pos); + } + + /** + * {@inheritDoc} + */ + public void renderPage(PageViewport page) throws IOException, FOPException { + log.debug("renderPage() " + page); + atts.clear(); + startElement("page"); + handlePageExtensionAttachments(page); + super.renderPage(page); + endElement("page"); + } + + private boolean parentHasTrait(Integer traitKey, Object trait) { + return ((parentArea != null + && parentArea.hasTrait(traitKey) + && parentArea.getTrait(traitKey).equals(trait))); + } + + /** + * Adds attributes from traits of an Area. + * @param area Area to extract traits from + */ + protected void addTraitAttributes(Area area) { + Object trait = area.getTrait(Trait.FONT); + if (trait != null && !parentHasTrait(Trait.FONT, trait)) { + FontTriplet fontTriplet = (FontTriplet)trait; + addAttribute("font-family", fontTriplet.getName()); + int weight = fontTriplet.getWeight(); + if (weight != Font.WEIGHT_NORMAL) { + addAttribute("font-weight", weight); + } + String style = fontTriplet.getStyle(); + if (!Font.STYLE_NORMAL.equals(style)) { + addAttribute("text-decoration", style); + } + } + trait = area.getTrait(Trait.FONT_SIZE); + if (trait != null && !parentHasTrait(Trait.FONT_SIZE, trait)) { + addAttribute("font-size", ((Integer)trait).intValue() / 1000); + } + trait = area.getTrait(Trait.COLOR); + if (trait != null && !parentHasTrait(Trait.COLOR, trait)) { + addColorAttribute("stroke", (Color)trait); + } + trait = area.getTrait(Trait.BACKGROUND); + if (trait != null && !parentHasTrait(Trait.BACKGROUND, trait)) { + addColorAttribute("fill", ((Background)trait).getColor()); + } + } + + private void addColorAttribute(String attrName, Color col) { + ColorSpace colSpace = col.getColorSpace(); + int colSpaceType = colSpace.getType(); + StringBuffer colStr = new StringBuffer(); + if (colSpace != null) { + if (colSpaceType == ColorSpace.TYPE_RGB) { + colStr.append("rgb("); + } else if (colSpaceType == ColorSpace.TYPE_CMYK) { + colStr.append("icc-color(myCMYK,"); + } else if (colSpaceType == ColorSpace.TYPE_GRAY) { + colStr.append("icc-color(myGRAY,"); + } + float[] colComp = col.getColorComponents(null); + for (int i = 0; i < colComp.length; i++) { + colStr.append((int)(colComp[i] * 255)); + colStr.append(","); + } + colStr.replace(colStr.length() - 1, colStr.length(), ")"); + } + addAttribute(attrName, colStr.toString()); + } + + /** + * {@inheritDoc} + */ + protected void renderText(TextArea text) { + log.debug("renderText() " + text); + atts.clear(); + this.currentText = ""; + addAttribute("x", text.getIPD()); + addAttribute("y", text.getAllocBPD()); + addTraitAttributes(text); + startElement("text", atts); + super.renderText(text); + try { + handler.characters(currentText.toCharArray(), 0, currentText.length()); + } catch (SAXException e) { + handleSAXException(e); + } + this.currentText = null; +// addAttribute("font-family", "Helvetica"); + endElement("text"); + } + + /** + * {@inheritDoc} + */ + protected void renderWord(WordArea word) { + log.debug("renderWord() " + word); + super.renderWord(word); + this.currentText += word.getWord(); + } + + /** + * {@inheritDoc} + */ + protected void renderSpace(SpaceArea space) { + log.debug("renderSpace() " + space); + super.renderSpace(space); + this.currentText += space.getSpace(); + } + + /** + * {@inheritDoc} + */ + public void renderImage(Image image, Rectangle2D pos) { + log.debug("renderImage() image=" + image + ", pos=" + pos); + super.renderImage(image, pos); + } + + protected void handleExtensionAttachments(List attachments) { + log.debug("handleExtensionAttachments() " + attachments); + if (attachments != null && attachments.size() > 0) { + } + } + + protected void endVParea() { + log.debug("endVParea()"); + } + + protected void renderInlineAreaBackAndBorders(InlineArea area) { + log.debug("renderInlineAreaBackAndBorders() " + area); + } + + protected void startVParea(CTM ctm, Rectangle2D clippingRect) { + log.debug("startVParea() ctm=" + ctm + ", rect=" + clippingRect); + } + + protected void renderBookmarkTree(BookmarkData odi) { + log.debug("renderBookmarkTree() odi=" + odi); + } + + /** {@inheritDoc} */ + public String getMimeType() { + return IF_MIME_TYPE; + } +} -- 2.39.5