diff options
author | Glenn Adams <gadams@apache.org> | 2016-03-12 05:39:53 +0000 |
---|---|---|
committer | Glenn Adams <gadams@apache.org> | 2016-03-12 05:39:53 +0000 |
commit | 6a719897d6f98ba89aa08e2f97b2b801be066cbf (patch) | |
tree | bcce1bb7e9c6bde85e1167cff6218948f5be9f0a /fop-sandbox | |
parent | 2184238c210288138b6703bd63ccb2c8c40300f0 (diff) | |
download | xmlgraphics-fop-6a719897d6f98ba89aa08e2f97b2b801be066cbf.tar.gz xmlgraphics-fop-6a719897d6f98ba89aa08e2f97b2b801be066cbf.zip |
Configure fop-{sandbox,servlet,transcoder}, checkstyle, findbugs; fixups for ant targets.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/maven@1734671 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'fop-sandbox')
30 files changed, 2961 insertions, 0 deletions
diff --git a/fop-sandbox/pom.xml b/fop-sandbox/pom.xml new file mode 100644 index 000000000..8d44f1443 --- /dev/null +++ b/fop-sandbox/pom.xml @@ -0,0 +1,142 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.xmlgraphics</groupId> + <artifactId>fop-sandbox</artifactId> + <name>Apache FOP Sandbox</name> + <description>XML Graphics Format Object Processor Sandbox</description> + + <parent> + <groupId>org.apache.xmlgraphics</groupId> + <artifactId>fop-parent</artifactId> + <version>2.2.0-SNAPSHOT</version> + </parent> + + <dependencies> + <!-- compile deps --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>fop-core</artifactId> + <version>${project.version}</version> + </dependency> + <!-- test deps --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <!-- generate event collector models --> + <!-- + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <version>${antrun.plugin.version}</version> + <executions> + <execution> + <id>codegen-events</id> + <phase>process-classes</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <taskdef name="collectEvents" classname="org.apache.fop.tools.EventProducerCollectorTask" classpathref="maven.compile.classpath"/> + <collectEvents destdir="${project.build.outputDirectory}"> + <fileset dir="${project.basedir}/src/main/java"> + <include name="**/accessibility/AccessibilityEventProducer.java"/> + </fileset> + </collectEvents> + </target> + </configuration> + </execution> + </executions> + </plugin> + --> + <!-- junit testing --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <includes> + <include>**/*TestCase.java</include> + </includes> + <redirectTestOutputToFile>true</redirectTestOutputToFile> + </configuration> + </plugin> + <!-- jar packaging --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifest> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + <mainClass>org.apache.fop.cli.Main</mainClass> + </manifest> + <manifestEntries> + <SpecificationTitle>XSL-FO - Extensible Stylesheet Language</SpecificationTitle> + <SpecificationVersion>1.1</SpecificationVersion> + <SpecificationVendor>World Wide Web Consortium</SpecificationVendor> + <SpecificationURL>http://www.w3.org/TR/xsl</SpecificationURL> + </manifestEntries> + </archive> + </configuration> + </plugin> + <!-- code analysis - checkstyle --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>${checkstyle.plugin.version}</version> + <configuration> + <configLocation>${project.baseUri}../fop-core/src/tools/resources/checkstyle/checkstyle.xml</configLocation> + <headerLocation>${project.baseUri}../fop-core/src/tools/resources/checkstyle/LICENSE.txt</headerLocation> + <includeResources>false</includeResources> + <includeTestResources>false</includeTestResources> + <linkXRef>false</linkXRef> + <logViolationsToConsole>true</logViolationsToConsole> + <suppressionsLocation>${project.baseUri}../fop-core/src/tools/resources/checkstyle/suppressions.xml</suppressionsLocation> + <violationSeverity>warning</violationSeverity> + </configuration> + </plugin> + <!-- code analysis - findbugs --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>findbugs-maven-plugin</artifactId> + <version>${findbugs.plugin.version}</version> + <configuration> + <excludeFilterFile>../fop-core/src/tools/resources/findbugs/exclusions.xml</excludeFilterFile> + <effort>Max</effort> + <threshold>Low</threshold> + </configuration> + </plugin> + </plugins> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + <resource> + <directory>${basedir}/..</directory> + <includes> + <include>LICENSE</include> + <include>NOTICE</include> + </includes> + <targetPath>META-INF</targetPath> + </resource> + </resources> + <testResources> + <testResource> + <directory>src/test/resources</directory> + <includes> + <include>**/*</include> + </includes> + </testResource> + </testResources> + </build> + +</project> diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFElement.java b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFElement.java new file mode 100644 index 000000000..098eab470 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFElement.java @@ -0,0 +1,131 @@ +/* + * 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.mif; + +// Java +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; + +/** + * The is the basis for MIF document elements. + * This enables the creation of the element and to write it + * to an output stream including sub-elements or a single value. + */ +public class MIFElement { + /** name */ + protected String name; + /** value string */ + protected String valueStr; + /** value elements */ + protected List valueElements; + /** true if started */ + protected boolean started; + /** true if finishing */ + protected boolean finish; + /** true if finished */ + protected boolean finished; + + /** + * @param name a name + */ + public MIFElement(String name) { + this.name = name; + } + + /** @param str a string value */ + public void setValue(String str) { + valueStr = str; + } + + /** @param el an MIF element */ + public void addElement(MIFElement el) { + if (valueElements == null) { + valueElements = new java.util.ArrayList(); + } + valueElements.add(el); + } + + /** + * Output this element to an output stream. + * This will output only so far as the fisrt unfinished child element. + * This method can be called again to continue from the previous point. + * An element that contains child elements will only be finished when + * the finish method is called. + * @param os output stream + * @param indent indentation + * @return true if finished + * @throws IOException if not caught + */ + public boolean output(OutputStream os, int indent) throws IOException { + if (finished) { + return true; + } + if (valueElements == null && valueStr == null) { + return false; + } + + String indentStr = ""; + for (int c = 0; c < indent; c++) { + indentStr += " "; + } + if (!started) { + os.write((indentStr + "<" + name).getBytes()); + if (valueElements != null) { + os.write(("\n").getBytes()); + } + started = true; + } + if (valueElements != null) { + boolean done = true; + for (Iterator iter = valueElements.iterator(); iter.hasNext();) { + MIFElement el = (MIFElement)iter.next(); + boolean d = el.output(os, indent + 1); + if (d) { + iter.remove(); + } else { + done = false; + break; + } + } + if (!finish || !done) { + return false; + } + os.write((indentStr + "> # end of " + name + "\n").getBytes()); + } else { + os.write((" " + valueStr + ">\n").getBytes()); + } + finished = true; + return true; + } + + /** @param deep if true, also perform finish over value elements */ + public void finish(boolean deep) { + finish = true; + if (deep && valueElements != null) { + for (Iterator iter = valueElements.iterator(); iter.hasNext();) { + MIFElement el = (MIFElement)iter.next(); + el.finish(deep); + } + } + } +} + diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFFOEventHandlerMaker.java b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFFOEventHandlerMaker.java new file mode 100644 index 000000000..31ce03dc3 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFFOEventHandlerMaker.java @@ -0,0 +1,52 @@ +/* + * 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.mif; + +import java.io.OutputStream; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.fo.FOEventHandler; +import org.apache.fop.render.AbstractFOEventHandlerMaker; + +/** + * Maker class for MIF support. + */ +public class MIFFOEventHandlerMaker extends AbstractFOEventHandlerMaker { + + private static final String[] MIMES = new String[] {MimeConstants.MIME_MIF}; + + + /** {@inheritDoc} */ + public FOEventHandler makeFOEventHandler(FOUserAgent ua, OutputStream out) { + return new MIFHandler(ua, out); + } + + /** {@inheritDoc} */ + public boolean needsOutputStream() { + return true; + } + + /** {@inheritDoc} */ + public String[] getSupportedMimeTypes() { + return MIMES; + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFFile.java b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFFile.java new file mode 100644 index 000000000..9ee8a8a5f --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFFile.java @@ -0,0 +1,159 @@ +/* + * 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.mif; + +// Java +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; + +/** + * The MIF File. + * This organises the MIF File and the corresponding elements. + * The catalog elements are used to setup the resources that + * are referenced. + */ +public class MIFFile extends MIFElement { + + /** colorCatalog */ + protected MIFElement colorCatalog; + /** pgfCatalog */ + protected PGFElement pgfCatalog; + /** fontCatalog */ + protected MIFElement fontCatalog; + /** rulingCatalog */ + protected RulingElement rulingCatalog; + /** tblCatalog */ + protected MIFElement tblCatalog; + /** views */ + protected MIFElement views; + /** variableFormats */ + protected MIFElement variableFormats; + /** xRefFormats */ + protected MIFElement xRefFormats; + /** document */ + protected MIFElement document; + /** bookComponent */ + protected MIFElement bookComponent; + /** initialAutoNums */ + protected MIFElement initialAutoNums; + /** aFrames */ + protected MIFElement aFrames; + /** tbls */ + protected MIFElement tbls; + /** pages */ + protected List pages = new java.util.ArrayList(); + /** textFlows */ + protected List textFlows; + + + /** default constructor */ + public MIFFile() { + super(""); + valueElements = new java.util.ArrayList(); + setup(); + } + + /** + * Do some setup. + * Currently adds some dummy values to the resources. + */ + protected void setup() { + MIFElement unit = new MIFElement("Units"); + unit.setValue("Ucm"); + addElement(unit); + + colorCatalog = new MIFElement("ColorCatalog"); + MIFElement color = new MIFElement("Color"); + MIFElement prop = new MIFElement("ColorTag"); + prop.setValue("`Black'"); + color.addElement(prop); + prop = new MIFElement("ColorCyan"); + prop.setValue("0.000000"); + color.addElement(prop); + + prop = new MIFElement("ColorMagenta"); + prop.setValue("0.000000"); + color.addElement(prop); + prop = new MIFElement("ColorYellow"); + prop.setValue("0.000000"); + color.addElement(prop); + prop = new MIFElement("ColorBlack"); + prop.setValue("100.000000"); + color.addElement(prop); + prop = new MIFElement("ColorAttribute"); + prop.setValue("ColorIsBlack"); + color.addElement(prop); + prop = new MIFElement("ColorAttribute"); + prop.setValue("ColorIsReserved"); + color.addElement(prop); + color.finish(true); + + colorCatalog.addElement(color); + addElement(colorCatalog); + + pgfCatalog = new PGFElement(); + pgfCatalog.lookupElement(null); + addElement(pgfCatalog); + + rulingCatalog = new RulingElement(); + rulingCatalog.lookupElement(null); + addElement(rulingCatalog); + + } + + /** + * @param os output stream + * @throws IOException if not caught + */ + public void output(OutputStream os) throws IOException { + if (finished) { + return; + } + + if (!started) { + os.write(("<MIFFile 5.00> # Generated by FOP\n"/* + getVersion()*/).getBytes()); + started = true; + } + boolean done = true; + + for (Iterator iter = valueElements.iterator(); iter.hasNext();) { + MIFElement el = (MIFElement)iter.next(); + boolean d = el.output(os, 0); + if (d) { + iter.remove(); + } else { + done = false; + break; + } + } + if (done && finish) { + os.write(("# end of MIFFile").getBytes()); + } + } + + /** @param p a page element to add */ + public void addPage(MIFElement p) { + pages.add(p); + addElement(p); + } +} + diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFHandler.java b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFHandler.java new file mode 100644 index 000000000..00b9dfbfe --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/MIFHandler.java @@ -0,0 +1,388 @@ +/* + * 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.mif; + +import java.io.IOException; +import java.io.OutputStream; + +import org.xml.sax.SAXException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.FOEventHandler; +import org.apache.fop.fo.FOText; +import org.apache.fop.fo.flow.BasicLink; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.Character; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.Footnote; +import org.apache.fop.fo.flow.FootnoteBody; +import org.apache.fop.fo.flow.Inline; +import org.apache.fop.fo.flow.InstreamForeignObject; +import org.apache.fop.fo.flow.Leader; +import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.flow.ListItem; +import org.apache.fop.fo.flow.ListItemBody; +import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.fo.flow.PageNumber; +import org.apache.fop.fo.flow.table.Table; +import org.apache.fop.fo.flow.table.TableBody; +import org.apache.fop.fo.flow.table.TableCell; +import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.flow.table.TableFooter; +import org.apache.fop.fo.flow.table.TableHeader; +import org.apache.fop.fo.flow.table.TableRow; +import org.apache.fop.fo.pagination.Flow; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.PageSequenceMaster; +import org.apache.fop.fo.pagination.SimplePageMaster; +import org.apache.fop.fo.pagination.StaticContent; +import org.apache.fop.fonts.FontSetup; + +// TODO: do we really want every method throwing a SAXException + +/** + * The MIF Handler. + * This generates MIF output using the structure events from + * the FO Tree sent to this structure handler. + * This builds an MIF file and writes it to the output. + */ +public class MIFHandler extends FOEventHandler { + + /** Logger */ + private static Log log = LogFactory.getLog(MIFHandler.class); + + /** the MIFFile instance */ + protected MIFFile mifFile; + + /** the OutputStream to write to */ + protected OutputStream outStream; + + // current state elements + private MIFElement textFlow; + private MIFElement para; + + /** + * Creates a new MIF handler on a given OutputStream. + * @param ua FOUserAgent instance for this process + * @param os OutputStream to write to + */ + public MIFHandler(FOUserAgent ua, OutputStream os) { + super(ua); + outStream = os; + boolean base14Kerning = false; //TODO - FIXME + FontSetup.setup(fontInfo, null, ua.getResourceResolver(), base14Kerning); + } + + /** {@inheritDoc} */ + public void startDocument() throws SAXException { + log.fatal("The MIF Handler is non-functional at this time. Please help resurrect it!"); + mifFile = new MIFFile(); + try { + mifFile.output(outStream); + } catch (IOException ioe) { + throw new SAXException(ioe); + } + } + + /** {@inheritDoc} */ + public void endDocument() throws SAXException { + // finish all open elements + mifFile.finish(true); + try { + mifFile.output(outStream); + outStream.flush(); + } catch (IOException ioe) { + throw new SAXException(ioe); + } + } + + /** {@inheritDoc} */ + public void startPageSequence(PageSequence pageSeq) { + // get the layout master set + // setup the pages for this sequence + String name = pageSeq.getMasterReference(); + SimplePageMaster spm = pageSeq.getRoot().getLayoutMasterSet().getSimplePageMaster(name); + if (spm == null) { + PageSequenceMaster psm + = pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(name); + } else { + // create simple master with regions + MIFElement prop = new MIFElement("PageType"); + prop.setValue("BodyPage"); + + MIFElement page = new MIFElement("Page"); + page.addElement(prop); + + prop = new MIFElement("PageBackground"); + prop.setValue("'Default'"); + page.addElement(prop); + + // build regions + MIFElement textRect = new MIFElement("TextRect"); + prop = new MIFElement("ID"); + prop.setValue("1"); + textRect.addElement(prop); + prop = new MIFElement("ShapeRect"); + prop.setValue("0.0 841.889 453.543 0.0"); + textRect.addElement(prop); + page.addElement(textRect); + + textRect = new MIFElement("TextRect"); + prop = new MIFElement("ID"); + prop.setValue("2"); + textRect.addElement(prop); + prop = new MIFElement("ShapeRect"); + prop.setValue("0.0 841.889 453.543 187.65"); + textRect.addElement(prop); + page.addElement(textRect); + + mifFile.addPage(page); + } + } + + /** {@inheritDoc} */ + public void endPageSequence(PageSequence pageSeq) { + } + + /** {@inheritDoc} */ + public void startFlow(Flow fl) { + // start text flow in body region + textFlow = new MIFElement("TextFlow"); + } + + /** {@inheritDoc} */ + public void endFlow(Flow fl) { + textFlow.finish(true); + mifFile.addElement(textFlow); + textFlow = null; + } + + /** {@inheritDoc} */ + public void startBlock(Block bl) { + para = new MIFElement("Para"); + // get font + textFlow.addElement(para); + } + + /** {@inheritDoc} */ + public void endBlock(Block bl) { + para.finish(true); + para = null; + } + + /** {@inheritDoc} */ + public void startInline(Inline inl) { + } + + /** {@inheritDoc} */ + public void endInline(Inline inl) { + } + + /** {@inheritDoc} */ + public void startTable(Table tbl) { + } + + /** {@inheritDoc} */ + public void endTable(Table tbl) { + } + + /** {@inheritDoc} */ + public void startColumn(TableColumn tc) { + } + + /** {@inheritDoc} */ + public void endColumn(TableColumn tc) { + } + + /** {@inheritDoc} */ + public void startHeader(TableHeader th) { + } + + /** {@inheritDoc} */ + public void endHeader(TableHeader th) { + } + + /** {@inheritDoc} */ + public void startFooter(TableFooter tf) { + } + + /** {@inheritDoc} */ + public void endFooter(TableFooter tf) { + } + + /** {@inheritDoc} */ + public void startBody(TableBody tb) { + } + + /** {@inheritDoc} */ + public void endBody(TableBody tb) { + } + + /** {@inheritDoc} */ + public void startRow(TableRow tr) { + } + + /** {@inheritDoc} */ + public void endRow(TableRow tr) { + } + + /** {@inheritDoc} */ + public void startCell(TableCell tc) { + } + + /** {@inheritDoc} */ + public void endCell(TableCell tc) { + } + + /** {@inheritDoc} */ + public void startList(ListBlock lb) { + } + + /** {@inheritDoc} */ + public void endList(ListBlock lb) { + } + + /** {@inheritDoc} */ + public void startListItem(ListItem li) { + } + + /** {@inheritDoc} */ + public void endListItem(ListItem li) { + } + + /** {@inheritDoc} */ + public void startListLabel(ListItemLabel listItemLabel) { + } + + /** {@inheritDoc} */ + public void endListLabel(ListItemLabel listItemLabel) { + } + + /** {@inheritDoc} */ + public void startListBody(ListItemBody listItemBody) { + } + + /** {@inheritDoc} */ + public void endListBody(ListItemBody listItemBody) { + } + + /** {@inheritDoc} */ + public void startStatic(StaticContent staticContent) { + } + + /** {@inheritDoc} */ + public void endStatic(StaticContent staticContent) { + } + + /** {@inheritDoc} */ + public void startMarkup() { + } + + /** {@inheritDoc} */ + public void endMarkup() { + } + + /** {@inheritDoc} */ + public void startLink(BasicLink basicLink) { + } + + /** {@inheritDoc} */ + public void endLink(BasicLink basicLink) { + } + + /** {@inheritDoc} */ + public void image(ExternalGraphic eg) { + } + + /** {@inheritDoc} */ + public void pageRef() { + } + + /** {@inheritDoc} */ + public void startInstreamForeignObject(InstreamForeignObject ifo) { + } + + /** {@inheritDoc} */ + public void endInstreamForeignObject(InstreamForeignObject ifo) { + } + + /** {@inheritDoc} */ + public void startFootnote(Footnote footnote) { + } + + /** {@inheritDoc} */ + public void endFootnote(Footnote footnote) { + } + + /** {@inheritDoc} */ + public void startFootnoteBody(FootnoteBody body) { + } + + /** {@inheritDoc} */ + public void endFootnoteBody(FootnoteBody body) { + } + + /** {@inheritDoc} */ + public void startLeader(Leader l) { + } + + /** {@inheritDoc} */ + public void endLeader(Leader l) { + } + + public void character(Character c) { + appendCharacters(new String(new char[] {c.getCharacter()})); + } + + /** {@inheritDoc} */ + public void characters(FOText foText) { + appendCharacters(foText.getCharSequence().toString()); + } + + /** {@inheritDoc} */ + public void startPageNumber(PageNumber pagenum) { + } + + /** {@inheritDoc} */ + public void endPageNumber(PageNumber pagenum) { + } + + private void appendCharacters(String str) { + if (para != null) { + str = str.trim(); + // break into nice length chunks + if (str.length() == 0) { + return; + } + MIFElement line = new MIFElement("ParaLine"); + MIFElement prop = new MIFElement("TextRectID"); + prop.setValue("2"); + line.addElement(prop); + prop = new MIFElement("String"); + prop.setValue("\"" + str + "\""); + line.addElement(prop); + para.addElement(line); + } + } +} + diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/PGFElement.java b/fop-sandbox/src/main/java/org/apache/fop/render/mif/PGFElement.java new file mode 100644 index 000000000..958518fac --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/PGFElement.java @@ -0,0 +1,53 @@ +/* + * 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.mif; + +/** + * Font Catalog element. + * This is the reference lookup element for fonts in + * the MIF document. + */ +public class PGFElement extends RefElement { + + /** + * Creates a new font catalog element. + */ + public PGFElement() { + super("PgfCatalog"); + } + + /** + * @param key an object + * @return an MIF element + */ + public MIFElement lookupElement(Object key) { + if (key == null) { + MIFElement pgf = new MIFElement("Pgf"); + MIFElement prop = new MIFElement("PgfTag"); + prop.setValue("`Body'"); + pgf.addElement(prop); + addElement(pgf); + pgf.finish(true); + return pgf; + } + return null; + } +} + diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/RefElement.java b/fop-sandbox/src/main/java/org/apache/fop/render/mif/RefElement.java new file mode 100644 index 000000000..0849f4f69 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/RefElement.java @@ -0,0 +1,49 @@ +/* + * 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.mif; + +/** + * Reference MIF Element. + * This element is a lookup reference set that contains + * a list of resources used in the MIF Document. + * When a lookup is performed it will either create a new + * element or return an existing element that is valid. + * THe key depends on the type of reference, it should be able + * to uniquely identify the element. + */ +public class RefElement extends MIFElement { + + /** + * @param name a name + * @see org.apache.fop.render.mif.MIFElement#MIFElement(String) + */ + public RefElement(String name) { + super(name); + } + + /** + * @param key a key + * @return an mif element + */ + public MIFElement lookupElement(Object key) { + return null; + } +} + diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/RulingElement.java b/fop-sandbox/src/main/java/org/apache/fop/render/mif/RulingElement.java new file mode 100644 index 000000000..c811a01a4 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/RulingElement.java @@ -0,0 +1,54 @@ +/* + * 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.mif; + +/** a ruling element */ +public class RulingElement extends RefElement { + + /** default constructor */ + public RulingElement() { + super("RulingCatalog"); + } + + /** {@inheritDoc} */ + public MIFElement lookupElement(Object key) { + if (key == null) { + MIFElement rul = new MIFElement("Ruling"); + MIFElement prop = new MIFElement("RulingTag"); + prop.setValue("`Default'"); + rul.addElement(prop); + prop = new MIFElement("RulingPenWidth"); + prop.setValue("1"); + rul.addElement(prop); + prop = new MIFElement("RulingPen"); + prop.setValue("0"); + rul.addElement(prop); + prop = new MIFElement("RulingLines"); + prop.setValue("1"); + rul.addElement(prop); + + addElement(rul); + rul.finish(true); + return rul; + } + return null; + } +} + diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/mif/package.html b/fop-sandbox/src/main/java/org/apache/fop/render/mif/package.html new file mode 100644 index 000000000..6a8e3054d --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/mif/package.html @@ -0,0 +1,23 @@ +<!-- + 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$ --> +<HTML> +<TITLE>org.apache.fop.render.mif Package</TITLE> +<BODY> +<P>MIF Output Support</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java new file mode 100644 index 000000000..091d904e5 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java @@ -0,0 +1,121 @@ +/* + * 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.IFContext; +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; + + public AbstractSVGDocumentHandler(IFContext context) { + super(context); + } + + /** {@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/fop-sandbox/src/main/java/org/apache/fop/render/svg/EmbeddedSVGImageHandler.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/EmbeddedSVGImageHandler.java new file mode 100644 index 000000000..371f5a768 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/EmbeddedSVGImageHandler.java @@ -0,0 +1,159 @@ +/* + * 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.Rectangle; +import java.io.IOException; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +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.Image; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; +import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; +import org.apache.xmlgraphics.util.QName; + +import org.apache.fop.image.loader.batik.BatikImageFlavors; +import org.apache.fop.render.ImageHandler; +import org.apache.fop.render.RenderingContext; +import org.apache.fop.render.intermediate.DelegatingFragmentContentHandler; + +/** + * Image handler implementation that embeds SVG images in the target SVG file. + */ +public class EmbeddedSVGImageHandler implements ImageHandler, SVGConstants { + + /** logging instance */ + private static Log log = LogFactory.getLog(EmbeddedSVGImageHandler.class); + + /** Constant for the "CDATA" attribute type. */ + private static final String CDATA = "CDATA"; + + /** {@inheritDoc} */ + public int getPriority() { + return 500; + } + + /** {@inheritDoc} */ + public Class getSupportedImageClass() { + return ImageRawStream.class; + } + + /** {@inheritDoc} */ + public ImageFlavor[] getSupportedImageFlavors() { + return new ImageFlavor[] { + BatikImageFlavors.SVG_DOM + }; + } + + private void addAttribute(AttributesImpl atts, QName attribute, String value) { + atts.addAttribute(attribute.getNamespaceURI(), + attribute.getLocalName(), attribute.getQName(), CDATA, value); + } + + /** {@inheritDoc} */ + public void handleImage(RenderingContext context, Image image, final Rectangle pos) + throws IOException { + SVGRenderingContext svgContext = (SVGRenderingContext)context; + ImageXMLDOM svg = (ImageXMLDOM)image; + ContentHandler handler = svgContext.getContentHandler(); + AttributesImpl atts = new AttributesImpl(); + atts.addAttribute("", "x", "x", CDATA, SVGUtil.formatMptToPt(pos.x)); + atts.addAttribute("", "y", "y", CDATA, SVGUtil.formatMptToPt(pos.y)); + atts.addAttribute("", "width", "width", CDATA, SVGUtil.formatMptToPt(pos.width)); + atts.addAttribute("", "height", "height", CDATA, SVGUtil.formatMptToPt(pos.height)); + try { + + Document doc = (Document)svg.getDocument(); + Element svgEl = (Element)doc.getDocumentElement(); + if (svgEl.getAttribute("viewBox").length() == 0) { + log.warn("SVG doesn't have a viewBox. The result might not be scaled correctly!"); + } + + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = tFactory.newTransformer(); + DOMSource src = new DOMSource(svg.getDocument()); + SAXResult res = new SAXResult(new DelegatingFragmentContentHandler(handler) { + + private boolean topLevelSVGFound; + + private void setAttribute(AttributesImpl atts, String localName, String value) { + int index; + index = atts.getIndex("", localName); + if (index < 0) { + atts.addAttribute("", localName, localName, CDATA, value); + } else { + atts.setAttribute(index, "", localName, localName, CDATA, value); + } + } + + public void startElement(String uri, String localName, String name, Attributes atts) + throws SAXException { + if (!topLevelSVGFound + && SVG_ELEMENT.getNamespaceURI().equals(uri) + && SVG_ELEMENT.getLocalName().equals(localName)) { + topLevelSVGFound = true; + AttributesImpl modAtts = new AttributesImpl(atts); + setAttribute(modAtts, "x", SVGUtil.formatMptToPt(pos.x)); + setAttribute(modAtts, "y", SVGUtil.formatMptToPt(pos.y)); + setAttribute(modAtts, "width", SVGUtil.formatMptToPt(pos.width)); + setAttribute(modAtts, "height", SVGUtil.formatMptToPt(pos.height)); + super.startElement(uri, localName, name, modAtts); + } else { + super.startElement(uri, localName, name, atts); + } + } + + }); + transformer.transform(src, res); + } catch (TransformerException te) { + throw new IOException(te.getMessage()); + } + } + + /** {@inheritDoc} */ + public boolean isCompatible(RenderingContext targetContext, Image image) { + if (targetContext instanceof SVGRenderingContext) { + if (image == null) { + return true; + } + if (image instanceof ImageXMLDOM) { + ImageXMLDOM svg = (ImageXMLDOM)image; + return NAMESPACE.equals(svg.getRootNamespace()); + } + } + return false; + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGConstants.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGConstants.java new file mode 100644 index 000000000..46e0b8da8 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGConstants.java @@ -0,0 +1,47 @@ +/* + * 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.apache.xmlgraphics.util.QName; + +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.util.XMLConstants; + +/** + * Constants for the intermediate format. + */ +public interface SVGConstants extends XMLConstants { + + /** MIME type for SVG. */ + String MIME_TYPE = MimeConstants.MIME_SVG; + + /** MIME type for SVG Print. */ + String MIME_SVG_PRINT = MimeConstants.MIME_SVG + ";profile=print"; + + /** File extension for SVG. */ + String FILE_EXTENSION_SVG = "svg"; + + /** XML namespace for SVG. */ + String NAMESPACE = "http://www.w3.org/2000/svg"; + + /** the SVG element */ + QName SVG_ELEMENT = new QName(NAMESPACE, null, "svg"); + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDataUrlImageHandler.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDataUrlImageHandler.java new file mode 100644 index 000000000..fbe29e8d5 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDataUrlImageHandler.java @@ -0,0 +1,106 @@ +/* + * 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.Rectangle; +import java.io.IOException; +import java.io.InputStream; + +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.xmlgraphics.image.loader.Image; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; +import org.apache.xmlgraphics.util.QName; +import org.apache.xmlgraphics.util.uri.DataURLUtil; + +import org.apache.fop.render.ImageHandler; +import org.apache.fop.render.RenderingContext; +import org.apache.fop.render.intermediate.IFConstants; + +/** + * Image handler implementation that embeds JPEG bitmaps as RFC 2397 data URLs in the target SVG + * file. + */ +public class SVGDataUrlImageHandler implements ImageHandler, SVGConstants { + + /** Constant for the "CDATA" attribute type. */ + private static final String CDATA = "CDATA"; + + /** {@inheritDoc} */ + public int getPriority() { + return 500; + } + + /** {@inheritDoc} */ + public Class getSupportedImageClass() { + return ImageRawStream.class; + } + + /** {@inheritDoc} */ + public ImageFlavor[] getSupportedImageFlavors() { + return new ImageFlavor[] { + ImageFlavor.RAW_PNG, + ImageFlavor.RAW_JPEG, + }; + } + + private void addAttribute(AttributesImpl atts, QName attribute, String value) { + atts.addAttribute(attribute.getNamespaceURI(), + attribute.getLocalName(), attribute.getQName(), CDATA, value); + } + + /** {@inheritDoc} */ + public void handleImage(RenderingContext context, Image image, Rectangle pos) + throws IOException { + SVGRenderingContext svgContext = (SVGRenderingContext)context; + ImageRawStream raw = (ImageRawStream)image; + InputStream in = raw.createInputStream(); + try { + ContentHandler handler = svgContext.getContentHandler(); + String url = DataURLUtil.createDataURL(in, raw.getMimeType()); + AttributesImpl atts = new AttributesImpl(); + addAttribute(atts, IFConstants.XLINK_HREF, url); + atts.addAttribute("", "x", "x", CDATA, Integer.toString(pos.x)); + atts.addAttribute("", "y", "y", CDATA, Integer.toString(pos.y)); + atts.addAttribute("", "width", "width", CDATA, Integer.toString(pos.width)); + atts.addAttribute("", "height", "height", CDATA, Integer.toString(pos.height)); + try { + handler.startElement(NAMESPACE, "image", "image", atts); + handler.endElement(NAMESPACE, "image", "image"); + } catch (SAXException e) { + throw new IOException(e.getMessage()); + } + } finally { + IOUtils.closeQuietly(in); + } + } + + /** {@inheritDoc} */ + public boolean isCompatible(RenderingContext targetContext, Image image) { + return (image == null || image instanceof ImageRawStream) + && targetContext instanceof SVGRenderingContext; + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDocumentHandler.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDocumentHandler.java new file mode 100644 index 000000000..f7bfbb38e --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDocumentHandler.java @@ -0,0 +1,275 @@ +/* + * 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 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.BitmapRendererEventProducer; +import org.apache.fop.render.bitmap.MultiFileRenderingUtil; +import org.apache.fop.render.intermediate.DelegatingFragmentContentHandler; +import org.apache.fop.render.intermediate.IFContext; +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; + +/** + * {@link org.apache.fop.render.intermediate.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; + + /** Used for single-page documents rendered to a DOM or SAX. */ + private Result simpleResult; + + private Document reusedParts; + + /** + * Default constructor. + */ + public SVGDocumentHandler(IFContext context) { + super(context); + } + + /** {@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 { + this.simpleResult = result; + } + } + + /** {@inheritDoc} */ + public void startDocument() throws IFException { + super.startDocument(); + 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, String pageMasterName, Dimension size) + throws IFException { + if (this.multiFileUtil != null) { + prepareHandlerWithOutputStream(index); + } else { + if (this.simpleResult == null) { + //Only one page is supported with this approach at the moment + throw new IFException( + "Only one page is supported for output with the given Result instance!", + null); + } + super.setResult(this.simpleResult); + this.simpleResult = null; + } + + 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", SVGUtil.formatMptToPt(size.width) + "pt"); + XMLUtil.addAttribute(atts, "height", SVGUtil.formatMptToPt(size.height) + "pt"); + XMLUtil.addAttribute(atts, "viewBox", + "0 0 " + SVGUtil.formatMptToPt(size.width) + + " " + SVGUtil.formatMptToPt(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 void prepareHandlerWithOutputStream(int index) throws IFException { + OutputStream out; + try { + if (index == 0) { + out = null; + } else { + out = this.multiFileUtil.createOutputStream(index); + if (out == null) { + BitmapRendererEventProducer eventProducer + = BitmapRendererEventProducer.Provider.get( + getUserAgent().getEventBroadcaster()); + eventProducer.stoppingAfterFirstPageNoFilename(this); + } + } + } 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)); + } + } + + private GenerationHelperContentHandler decorate(ContentHandler contentHandler) { + return new GenerationHelperContentHandler(contentHandler, getMainNamespace(), getContext()); + } + + 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/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java new file mode 100644 index 000000000..75fc8b70e --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java @@ -0,0 +1,48 @@ +/* + * 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.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker; +import org.apache.fop.render.intermediate.IFContext; +import org.apache.fop.render.intermediate.IFDocumentHandler; + +/** + * Document handler factory for SVG output. + */ +public class SVGDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker { + + private static final String[] MIMES = new String[] {SVGConstants.MIME_TYPE}; + + /** {@inheritDoc} */ + public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) { + return new SVGDocumentHandler(ifContext); + } + + /** {@inheritDoc} */ + public boolean needsOutputStream() { + return true; + } + + /** {@inheritDoc} */ + public String[] getSupportedMimeTypes() { + return MIMES; + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPainter.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPainter.java new file mode 100644 index 000000000..fb7ce2677 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPainter.java @@ -0,0 +1,418 @@ +/* + * 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.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.xmp.Metadata; + +import org.apache.fop.ResourceEventProducer; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.ImageHandlerUtil; +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.XMLConstants; +import org.apache.fop.util.XMLUtil; + +/** + * IFPainter implementation that writes SVG. + */ +public class SVGPainter extends AbstractIFPainter<AbstractSVGDocumentHandler> + implements SVGConstants { + + /** The SAX content handler that receives the generated XML events. */ + private GenerationHelperContentHandler handler; + + private static final int MODE_NORMAL = 0; + private static final int MODE_TEXT = 1; + + private int mode = MODE_NORMAL; + + /** + * Main constructor. + * @param parent the parent document handler + * @param contentHandler the target SAX content handler + */ + public SVGPainter(AbstractSVGDocumentHandler parent, + GenerationHelperContentHandler contentHandler) { + super(parent); + this.handler = contentHandler; + this.state = IFState.create(); + } + + /** {@inheritDoc} */ + public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect) + throws IFException { + startViewport(SVGUtil.formatAffineTransformMptToPt(transform), size, clipRect); + } + + /** {@inheritDoc} */ + public void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect) + throws IFException { + startViewport(SVGUtil.formatAffineTransformsMptToPt(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) { + XMLUtil.addAttribute(atts, "transform", transform); + } + handler.startElement("g", atts); + + atts.clear(); + XMLUtil.addAttribute(atts, "width", SVGUtil.formatMptToPt(size.width)); + XMLUtil.addAttribute(atts, "height", SVGUtil.formatMptToPt(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(SVGUtil.formatMptToPt(v[0])).append(','); + sb.append(SVGUtil.formatMptToPt(v[1])).append(','); + sb.append(SVGUtil.formatMptToPt(v[2])).append(','); + sb.append(SVGUtil.formatMptToPt(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 { + establish(MODE_NORMAL); + handler.endElement("svg"); + handler.endElement("g"); + } catch (SAXException e) { + throw new IFException("SAX error in endBox()", e); + } + } + + /** {@inheritDoc} */ + public void startGroup(AffineTransform[] transforms, String layer) throws IFException { + startGroup(SVGUtil.formatAffineTransformsMptToPt(transforms), layer); + } + + /** {@inheritDoc} */ + public void startGroup(AffineTransform transform, String layer) throws IFException { + startGroup(SVGUtil.formatAffineTransformMptToPt(transform), layer); + } + + private void startGroup(String transform, String layer) throws IFException { + try { + 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 startGroup()", e); + } + } + + /** {@inheritDoc} */ + 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 drawImage(String uri, Rectangle rect) throws IFException { + try { + establish(MODE_NORMAL); + + ImageManager manager = getUserAgent().getImageManager(); + ImageInfo info = null; + try { + ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); + info = manager.getImageInfo(uri, sessionContext); + + String mime = info.getMimeType(); + Map foreignAttributes = getContext().getForeignAttributes(); + String conversionMode = (String)foreignAttributes.get( + ImageHandlerUtil.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", SVGUtil.formatMptToPt(rect.x)); + XMLUtil.addAttribute(atts, "y", SVGUtil.formatMptToPt(rect.y)); + XMLUtil.addAttribute(atts, "width", SVGUtil.formatMptToPt(rect.width)); + XMLUtil.addAttribute(atts, "height", SVGUtil.formatMptToPt(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 (SAXException e) { + throw new IFException("SAX error in drawImage()", e); + } + } + + /** {@inheritDoc} */ + public void drawImage(Document doc, Rectangle rect) 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 clipBackground(Rectangle rect, BorderProps bpsBefore, BorderProps bpsAfter, + BorderProps bpsStart, BorderProps bpsEnd) 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(); + XMLUtil.addAttribute(atts, "x", SVGUtil.formatMptToPt(rect.x)); + XMLUtil.addAttribute(atts, "y", SVGUtil.formatMptToPt(rect.y)); + XMLUtil.addAttribute(atts, "width", SVGUtil.formatMptToPt(rect.width)); + XMLUtil.addAttribute(atts, "height", SVGUtil.formatMptToPt(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 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(); + XMLUtil.addAttribute(atts, "x1", SVGUtil.formatMptToPt(start.x)); + XMLUtil.addAttribute(atts, "y1", SVGUtil.formatMptToPt(start.y)); + XMLUtil.addAttribute(atts, "x2", SVGUtil.formatMptToPt(end.x)); + XMLUtil.addAttribute(atts, "y2", SVGUtil.formatMptToPt(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 drawLine()", e); + } + } + + /** {@inheritDoc} */ + + public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[][] dp, + String text) throws IFException { + try { + establish(MODE_TEXT); + AttributesImpl atts = new AttributesImpl(); + XMLUtil.addAttribute(atts, XMLConstants.XML_SPACE, "preserve"); + XMLUtil.addAttribute(atts, "x", SVGUtil.formatMptToPt(x)); + XMLUtil.addAttribute(atts, "y", SVGUtil.formatMptToPt(y)); + if (letterSpacing != 0) { + XMLUtil.addAttribute(atts, "letter-spacing", SVGUtil.formatMptToPt(letterSpacing)); + } + if (wordSpacing != 0) { + XMLUtil.addAttribute(atts, "word-spacing", SVGUtil.formatMptToPt(wordSpacing)); + } + if (dp != null) { + int[] dx = IFUtil.convertDPToDX(dp); + XMLUtil.addAttribute(atts, "dx", SVGUtil.formatMptArrayToPt(dx)); + } + 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 setFont()", e); + } + } + + 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", SVGUtil.formatMptToPt(state.getFontSize())); + XMLUtil.addAttribute(atts, "fill", toString(state.getTextColor())); + handler.startElement("g", atts); + state.resetFontChanged(); + } + + /** + * @param extension an extension object + * @throws IFException if not caught + */ + 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); + } + } + + /** {@inheritDoc} */ + public void fillBackground(Rectangle rect, Paint fill, BorderProps bpsBefore, + BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) throws IFException { + // Not supported in SVG + + } + + + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPrintDocumentHandler.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPrintDocumentHandler.java new file mode 100644 index 000000000..b97d3d261 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPrintDocumentHandler.java @@ -0,0 +1,170 @@ +/* + * 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 org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.apache.fop.render.intermediate.IFConstants; +import org.apache.fop.render.intermediate.IFContext; +import org.apache.fop.render.intermediate.IFException; +import org.apache.fop.render.intermediate.IFPainter; +import org.apache.fop.util.XMLUtil; + +/** + * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation + * that writes SVG Print. + */ +public class SVGPrintDocumentHandler extends AbstractSVGDocumentHandler { + + /** + * Default constructor. + */ + public SVGPrintDocumentHandler(IFContext context) { + super(context); + } + + /** {@inheritDoc} */ + public boolean supportsPagesOutOfOrder() { + return false; + } + + /** {@inheritDoc} */ + public String getMimeType() { + return MIME_SVG_PRINT; + } + + /** {@inheritDoc} */ + public void startDocument() throws IFException { + super.startDocument(); + try { + handler.startDocument(); + handler.startPrefixMapping("", NAMESPACE); + handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE); + handler.startPrefixMapping("if", IFConstants.NAMESPACE); + AttributesImpl atts = new AttributesImpl(); + 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); + } + } + + /** {@inheritDoc} */ + public void endDocument() throws IFException { + try { + handler.endElement("svg"); + handler.endDocument(); + } catch (SAXException e) { + throw new IFException("SAX error in endDocument()", e); + } + } + + /** {@inheritDoc} */ + public void startPageSequence(String id) throws IFException { + try { + AttributesImpl atts = new AttributesImpl(); + if (id != null) { + atts.addAttribute(XML_NAMESPACE, "id", "xml:id", CDATA, id); + } + handler.startElement("pageSet", atts); + } catch (SAXException e) { + throw new IFException("SAX error in startPageSequence()", e); + } + } + + /** {@inheritDoc} */ + public void endPageSequence() throws IFException { + try { + handler.endElement("pageSet"); + } catch (SAXException e) { + throw new IFException("SAX error in endPageSequence()", e); + } + } + + /** {@inheritDoc} */ + public void startPage(int index, String name, String pageMasterName, Dimension size) + throws IFException { + try { + AttributesImpl atts = new AttributesImpl(); + /* + 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", + CDATA, Integer.toString(size.width)); + atts.addAttribute(IFConstants.NAMESPACE, "height", "if:height", + CDATA, Integer.toString(size.height)); + atts.addAttribute(IFConstants.NAMESPACE, "viewBox", "if:viewBox", CDATA, + "0 0 " + Integer.toString(size.width) + " " + Integer.toString(size.height)); + handler.startElement("page", atts); + } catch (SAXException e) { + throw new IFException("SAX error in startPage()", e); + } + } + + /** {@inheritDoc} */ + public void startPageHeader() throws IFException { + } + + /** {@inheritDoc} */ + public void endPageHeader() throws IFException { + } + + /** {@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 startPageTrailer() throws IFException { + } + + /** {@inheritDoc} */ + public void endPageTrailer() throws IFException { + } + + /** {@inheritDoc} */ + public void endPage() throws IFException { + try { + handler.endElement("page"); + } catch (SAXException e) { + throw new IFException("SAX error in endPage()", e); + } + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java new file mode 100644 index 000000000..0a0e599ff --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java @@ -0,0 +1,48 @@ +/* + * 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.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker; +import org.apache.fop.render.intermediate.IFContext; +import org.apache.fop.render.intermediate.IFDocumentHandler; + +/** + * Document handler factory for SVG Print output. + */ +public class SVGPrintDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker { + + private static final String[] MIMES = new String[] {SVGConstants.MIME_SVG_PRINT}; + + /** {@inheritDoc} */ + public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) { + return new SVGPrintDocumentHandler(ifContext); + } + + /** {@inheritDoc} */ + public boolean needsOutputStream() { + return true; + } + + /** {@inheritDoc} */ + public String[] getSupportedMimeTypes() { + return MIMES; + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRenderer.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRenderer.java new file mode 100644 index 000000000..9cbc1662d --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRenderer.java @@ -0,0 +1,177 @@ +/* + * 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.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.batik.dom.GenericDOMImplementation; +import org.apache.batik.svggen.SVGGeneratorContext; +import org.apache.batik.svggen.SVGGraphics2D; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.area.PageViewport; +import org.apache.fop.render.bitmap.MultiFileRenderingUtil; +import org.apache.fop.render.java2d.Java2DGraphicsState; +import org.apache.fop.render.java2d.Java2DRenderer; + +/** + * <p> + * This renderer generates SVG (Scalable Vector Graphics) format. + * <p> + * This class actually does not render itself, instead it extends + * <code>org.apache.fop.render.java2D.Java2DRenderer</code> and uses + * Apache Batik's SVGGraphics2D for SVG generation. + */ +public class SVGRenderer extends Java2DRenderer { + + /** logging instance */ + private static Log log = LogFactory.getLog(SVGRenderer.class); + + /** The MIME type for the SVG format */ + public static final String MIME_TYPE = MimeConstants.MIME_SVG; + + private static final String SVG_FILE_EXTENSION = "svg"; + + private OutputStream firstOutputStream; + + private Document document; + + private SVGGraphics2D svgGenerator; + + /** Helper class for generating multiple files */ + private MultiFileRenderingUtil multiFileUtil; + + /** + * @param userAgent the user agent that contains configuration details. This cannot be null. + */ + public SVGRenderer(FOUserAgent userAgent) { + super(userAgent); + } + + /** {@inheritDoc} */ + public String getMimeType() { + return MIME_TYPE; + } + + /** {@inheritDoc} */ + public void startRenderer(OutputStream outputStream) throws IOException { + this.firstOutputStream = outputStream; + this.multiFileUtil = new MultiFileRenderingUtil(SVG_FILE_EXTENSION, + getUserAgent().getOutputFile()); + super.startRenderer(this.firstOutputStream); + } + + /** {@inheritDoc} */ + public void renderPage(PageViewport pageViewport) throws IOException { + log.debug("Rendering page: " + pageViewport.getPageNumberString()); + // Get a DOMImplementation + DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); + + // Create an instance of org.w3c.dom.Document + this.document = domImpl.createDocument(null, "svg", null); + + // Create an SVGGeneratorContext to customize SVG generation + SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(this.document); + ctx.setComment("Generated by " + userAgent.getProducer() + " with Batik SVG Generator"); + ctx.setEmbeddedFontsOn(true); + + // Create an instance of the SVG Generator + this.svgGenerator = new SVGGraphics2D(ctx, true); + Rectangle2D viewArea = pageViewport.getViewArea(); + Dimension dim = new Dimension(); + dim.setSize(viewArea.getWidth() / 1000, viewArea.getHeight() / 1000); + this.svgGenerator.setSVGCanvasSize(dim); + + AffineTransform at = this.svgGenerator.getTransform(); + this.state = new Java2DGraphicsState(this.svgGenerator, this.fontInfo, at); + try { + //super.renderPage(pageViewport); + renderPageAreas(pageViewport.getPage()); + } finally { + this.state = null; + } + writeSVGFile(pageViewport.getPageIndex()); + + this.svgGenerator = null; + this.document = null; + + } + + /** {@inheritDoc} */ + public void stopRenderer() throws IOException { + super.stopRenderer(); + + // Cleaning + clearViewportList(); + log.debug("SVG generation complete."); + } + + private void writeSVGFile(int pageNumber) throws IOException { + log.debug("Writing out SVG file..."); + // Finally, stream out SVG to the standard output using UTF-8 + // character to byte encoding + boolean useCSS = true; // we want to use CSS style attribute + OutputStream out = getCurrentOutputStream(pageNumber); + if (out == null) { + log.warn("No filename information available." + + " Stopping early after the first page."); + return; + } + try { + Writer writer = new java.io.OutputStreamWriter(out, "UTF-8"); + this.svgGenerator.stream(writer, useCSS); + } finally { + if (out != this.firstOutputStream) { + IOUtils.closeQuietly(out); + } else { + out.flush(); + } + } + } + + /** + * Returns the OutputStream corresponding to this page + * @param pageNumber 0-based page number + * @return the corresponding OutputStream + * @throws IOException In case of an I/O error + */ + protected OutputStream getCurrentOutputStream(int pageNumber) throws IOException { + if (pageNumber == 0) { + return firstOutputStream; + } else { + return multiFileUtil.createOutputStream(pageNumber); + } + + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRendererContextConstants.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRendererContextConstants.java new file mode 100644 index 000000000..789db898e --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRendererContextConstants.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.svg; + +import org.apache.fop.render.RendererContextConstants; + +/** + * Defines a number of standard constants (keys) for use by the RendererContext class. + */ +public interface SVGRendererContextConstants extends RendererContextConstants { + + /** The SVG document that this image is being drawn into. */ + String SVG_DOCUMENT = "svgDoc"; + + /** The current SVG page g element. */ + String SVG_PAGE_G = "svgPageG"; + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRendererMaker.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRendererMaker.java new file mode 100644 index 000000000..95c4effbb --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRendererMaker.java @@ -0,0 +1,54 @@ +/* + * 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.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.AbstractRendererMaker; +import org.apache.fop.render.Renderer; + +/** + * RendererMaker for the SVG Renderer. + */ +public class SVGRendererMaker extends AbstractRendererMaker { + + private static final String[] MIMES = new String[] {MimeConstants.MIME_SVG}; + + @Override + public Renderer makeRenderer(FOUserAgent ua) { + return new SVGRenderer(ua); + } + + @Override + public boolean needsOutputStream() { + return true; + } + + @Override + public String[] getSupportedMimeTypes() { + return MIMES; + } + + @Override + public void configureRenderer(FOUserAgent userAgent, Renderer renderer) throws FOPException { + // No-Op + } +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRenderingContext.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRenderingContext.java new file mode 100644 index 000000000..5e64af677 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGRenderingContext.java @@ -0,0 +1,59 @@ +/* + * 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.ContentHandler; + +import org.apache.xmlgraphics.util.MimeConstants; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.render.AbstractRenderingContext; + +/** + * Rendering context for SVG production. + */ +public class SVGRenderingContext extends AbstractRenderingContext { + + private ContentHandler handler; + + /** + * Main constructor. + * @param userAgent the user agent + * @param handler the target content handler + */ + public SVGRenderingContext(FOUserAgent userAgent, ContentHandler handler) { + super(userAgent); + this.handler = handler; + } + + /** {@inheritDoc} */ + public String getMimeType() { + return MimeConstants.MIME_SVG; + } + + /** + * Returns the target content handler. + * @return the content handler + */ + public ContentHandler getContentHandler() { + return this.handler; + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGSVGHandler.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGSVGHandler.java new file mode 100644 index 000000000..9c571db97 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGSVGHandler.java @@ -0,0 +1,84 @@ +/* + * 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.w3c.dom.DOMImplementation; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.svg.SVGDocument; +import org.w3c.dom.svg.SVGElement; +import org.w3c.dom.svg.SVGSVGElement; + +import org.apache.batik.anim.dom.SVGDOMImplementation; +import org.apache.batik.dom.util.DOMUtilities; +import org.apache.batik.dom.util.XMLSupport; + +import org.apache.fop.render.Renderer; +import org.apache.fop.render.RendererContext; +import org.apache.fop.render.XMLHandler; + +/** The svg:svg element handler. */ +public class SVGSVGHandler implements XMLHandler, SVGRendererContextConstants { + + /** {@inheritDoc} */ + public void handleXML(RendererContext context, + org.w3c.dom.Document doc, String ns) throws Exception { + if (getNamespace().equals(ns)) { + if (!(doc instanceof SVGDocument)) { + DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); + doc = DOMUtilities.deepCloneDocument(doc, impl); + } + SVGSVGElement svg = ((SVGDocument) doc).getRootElement(); + SVGDocument targetDoc = (SVGDocument)context.getProperty(SVG_DOCUMENT); + SVGElement currentPageG = (SVGElement)context.getProperty(SVG_PAGE_G); + Element view = targetDoc.createElementNS(getNamespace(), "svg"); + Node newsvg = targetDoc.importNode(svg, true); + //view.setAttributeNS(null, "viewBox", "0 0 "); + int xpos = ((Integer)context.getProperty(XPOS)).intValue(); + int ypos = ((Integer)context.getProperty(YPOS)).intValue(); + view.setAttributeNS(null, "x", "" + xpos / 1000f); + view.setAttributeNS(null, "y", "" + ypos / 1000f); + + // this fixes a problem where the xmlns is repeated sometimes + Element ele = (Element) newsvg; + ele.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns", + getNamespace()); + if (ele.hasAttributeNS(null, "xmlns")) { + ele.removeAttributeNS(null, "xmlns"); + } + + view.appendChild(newsvg); + currentPageG.appendChild(view); + } + } + + + /** {@inheritDoc} */ + public boolean supportsRenderer(Renderer renderer) { + return (renderer instanceof SVGRenderer); + } + + /** {@inheritDoc} */ + public String getNamespace() { + return SVGRenderer.MIME_TYPE; + } + + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGUtil.java b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGUtil.java new file mode 100644 index 000000000..186789dac --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/SVGUtil.java @@ -0,0 +1,81 @@ +/* + * 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.geom.AffineTransform; + +import org.apache.fop.render.intermediate.IFUtil; + +/** + * This class provides utility methods for generating SVG. + */ +public final class SVGUtil { + + private SVGUtil() { + } + + /** + * Formats a length in millipoints as a point value. + * @param mpt the length in millipoints + * @return the formatted value in points + */ + public static String formatMptToPt(int mpt) { + return Float.toString(mpt / 1000f); + } + + /** + * Formats an array of lengths in millipoints as point values. + * @param lengths the lengths in millipoints + * @return the formatted array in points + */ + public static String formatMptArrayToPt(int[] lengths) { + return IFUtil.toString(lengths); + } + + /** + * Formats a transformation matrix in millipoints with values as points. + * @param transform the transformation matrix in millipoints + * @return the formatted matrix in points + */ + public static String formatAffineTransformMptToPt(AffineTransform transform) { + AffineTransform scaled = new AffineTransform(transform); + scaled.setToTranslation( + transform.getTranslateX() / 1000, + transform.getTranslateY() / 1000); + return IFUtil.toString(scaled); + } + + /** + * Formats an array of transformation matrices in millipoints with values as points. + * @param transforms the transformation matrices in millipoints + * @return the formatted matrices in points + */ + public static String formatAffineTransformsMptToPt(AffineTransform[] transforms) { + StringBuffer sb = new StringBuffer(); + for (int i = 0, c = transforms.length; i < c; i++) { + if (i > 0) { + sb.append(' '); + } + sb.append(formatAffineTransformMptToPt(transforms[i])); + } + return sb.toString(); + } + +} diff --git a/fop-sandbox/src/main/java/org/apache/fop/render/svg/package.html b/fop-sandbox/src/main/java/org/apache/fop/render/svg/package.html new file mode 100644 index 000000000..977c7d183 --- /dev/null +++ b/fop-sandbox/src/main/java/org/apache/fop/render/svg/package.html @@ -0,0 +1,23 @@ +<!-- + 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$ --> +<HTML> +<TITLE>org.apache.fop.render.svg Package</TITLE> +<BODY> +<P>SVG (Structured Vector Graphics) Renderer</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.fo.ElementMapping b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.fo.ElementMapping new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.fo.ElementMapping diff --git a/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.fo.FOEventHandler b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.fo.FOEventHandler new file mode 100644 index 000000000..8fe7aac6e --- /dev/null +++ b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.fo.FOEventHandler @@ -0,0 +1 @@ +org.apache.fop.render.mif.MIFFOEventHandlerMaker
\ No newline at end of file diff --git a/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.ImageHandler b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.ImageHandler new file mode 100644 index 000000000..49af6340e --- /dev/null +++ b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.ImageHandler @@ -0,0 +1,2 @@ +org.apache.fop.render.svg.SVGDataUrlImageHandler
+org.apache.fop.render.svg.EmbeddedSVGImageHandler
diff --git a/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.XMLHandler b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.XMLHandler new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.XMLHandler diff --git a/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.intermediate.IFDocumentHandler b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.intermediate.IFDocumentHandler new file mode 100644 index 000000000..5ed153ac3 --- /dev/null +++ b/fop-sandbox/src/main/resources/META-INF/services/org.apache.fop.render.intermediate.IFDocumentHandler @@ -0,0 +1,2 @@ +org.apache.fop.render.svg.SVGDocumentHandlerMaker
+org.apache.fop.render.svg.SVGPrintDocumentHandlerMaker
\ No newline at end of file |