diff --git a/java/libraries/svg/README.md b/java/libraries/svg/README.md new file mode 100644 index 000000000..6c04ab449 --- /dev/null +++ b/java/libraries/svg/README.md @@ -0,0 +1 @@ +A very simple SVG exporter based on the PDF Export library that ships with Processing. Uses Batik's [SVG Generator](http://xmlgraphics.apache.org/batik/using/svg-generator.html). diff --git a/java/libraries/svg/build.xml b/java/libraries/svg/build.xml new file mode 100644 index 000000000..e75f87dd7 --- /dev/null +++ b/java/libraries/svg/build.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/libraries/svg/library/LICENSE b/java/libraries/svg/library/LICENSE new file mode 100644 index 000000000..3e4e3d004 --- /dev/null +++ b/java/libraries/svg/library/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. \ No newline at end of file diff --git a/java/libraries/svg/library/export.txt b/java/libraries/svg/library/export.txt new file mode 100644 index 000000000..d3f3e9255 --- /dev/null +++ b/java/libraries/svg/library/export.txt @@ -0,0 +1 @@ +name = SVG Export diff --git a/java/libraries/svg/src/WriteSVG.java b/java/libraries/svg/src/WriteSVG.java new file mode 100644 index 000000000..7a48803ca --- /dev/null +++ b/java/libraries/svg/src/WriteSVG.java @@ -0,0 +1,32 @@ +import processing.core.PApplet; + +public class WriteSVG extends PApplet { + + public String sketchRenderer() { + return "processing.svg.PGraphicsSVG"; + } + + + public String sketchOutputPath() { + return "/Users/fry/Desktop/frame-####.svg"; + } + + + public void setup() { + size(600, 400, "processing.svg.PGraphicsSVG", "/Users/fry/Desktop/frame-####.svg"); +// frameRate(1); + } + + public void draw() { + background(random(255)); + stroke(random(255)); + strokeWeight(20); + line(random(width), random(height), random(width), random(height)); + if (frameCount == 5) exit(); +// exit(); + } + + static public void main(String[] args) { + PApplet.main(new String[] { "WriteSVG" }); + } +} \ No newline at end of file diff --git a/java/libraries/svg/src/processing/svg/PGraphicsSVG.java b/java/libraries/svg/src/processing/svg/PGraphicsSVG.java new file mode 100644 index 000000000..86fc4c561 --- /dev/null +++ b/java/libraries/svg/src/processing/svg/PGraphicsSVG.java @@ -0,0 +1,524 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2013-2015 The Processing Foundation + Copyright (c) 2012 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.svg; + +import java.awt.Dimension; +import java.io.*; + +import org.apache.batik.svggen.SVGGraphics2D; +import org.apache.batik.svggen.SVGGraphics2DIOException; +import org.apache.batik.dom.GenericDOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.DOMImplementation; + +import processing.core.*; + + +public class PGraphicsSVG extends PGraphicsJava2D { + /** File being written, if it's a file. */ + protected File file; + /** OutputStream being written to, if using an OutputStream. */ + protected OutputStream output; + +// protected Writer writer; + + + public PGraphicsSVG() { } + + + public void setPath(String path) { + this.path = path; + if (path != null) { + file = new File(path); + if (!file.isAbsolute()) { + file = null; + } + } + if (file == null) { + throw new RuntimeException("PGraphicsSVG requires an absolute path " + + "for the location of the output file."); + } + } + + + /** + * Set the library to write to an output stream instead of a file. + */ + public void setOutput(OutputStream output) { + this.output = output; + } + + + @Override + public PSurface createSurface() { + return surface = new PSurfaceNone(this); + } + + + protected void defaultSettings() { // ignore + super.defaultSettings(); + textMode = SHAPE; + } + + + public void beginDraw() { + DOMImplementation domImpl = + GenericDOMImplementation.getDOMImplementation(); + + // Create an instance of org.w3c.dom.Document. + String ns = "http://www.w3.org/2000/svg"; + Document document = domImpl.createDocument(ns, "svg", null); + + // Create an instance of the SVG Generator. + g2 = new SVGGraphics2D(document); + ((SVGGraphics2D) g2).setSVGCanvasSize(new Dimension(width, height)); + + // Done with our work, let's check on defaults and the rest + //super.beginDraw(); + // Can't call super.beginDraw() because it'll nuke our g2 + checkSettings(); + resetMatrix(); // reset model matrix + vertexCount = 0; + + // Also need to push the matrix since the matrix doesn't reset on each run + // http://dev.processing.org/bugs/show_bug.cgi?id=1227 + pushMatrix(); + } + + + public void endDraw() { + // Also need to pop the matrix since the matrix doesn't reset on each run + // http://dev.processing.org/bugs/show_bug.cgi?id=1227 + popMatrix(); + + // Figure out where the output goes. If the sketch is calling setOutput() + // inside draw(), then that OutputStream will be used, otherwise the + // path for rendering is expected to have ### inside it so that the frame + // can be inserted, because SVG doesn't support multiple pages. + if (output == null) { + if (path == null) { + throw new RuntimeException("setOutput() or setPath() must be " + + "used with the SVG renderer"); + } else { + // insert the frame number and create intermediate directories + File file = parent.saveFile(parent.insertFrame(path)); + try { + output = new FileOutputStream(file); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + } + + // This needs to be overridden so that the endDraw() from PGraphicsJava2D + // is not inherited (it calls loadPixels). + // http://dev.processing.org/bugs/show_bug.cgi?id=1169 + + // Finally, stream out SVG to the standard output using UTF-8 encoding. + boolean useCSS = true; // we want to use CSS style attributes + Writer writer = PApplet.createWriter(output); +// Writer out = new OutputStreamWriter(System.out, "UTF-8"); + try { + ((SVGGraphics2D) g2).stream(writer, useCSS); + } catch (SVGGraphics2DIOException e) { + e.printStackTrace(); + } + try { + writer.flush(); + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + output = null; + } + } + + +// /** +// * Call to explicitly go to the next page from within a single draw(). +// */ +// public void nextPage() { +// PStyle savedStyle = getStyle(); +// endDraw(); +// g2.dispose(); +// +// try { +//// writer.setPageEmpty(false); // maybe useful later +// document.newPage(); // is this bad if no addl pages are made? +// } catch (Exception e) { +// e.printStackTrace(); +// } +// g2 = createGraphics(); +// beginDraw(); +// style(savedStyle); +// } + + +// protected Graphics2D createGraphics() { +// if (textMode == SHAPE) { +// return content.createGraphicsShapes(width, height); +// } else if (textMode == MODEL) { +// return content.createGraphics(width, height, getMapper()); +// } +// // Should not be reachable... +// throw new RuntimeException("Invalid textMode() selected for PDF."); +// } + + + // nothing to be done in dispose(), since essentially disposed on each frame + public void dispose() { +// if (document != null) { +// g2.dispose(); +// document.close(); // can't be done in finalize, not always called +// document = null; +// } +// //new Exception().printStackTrace(System.out); + } + + + /** + * Don't open a window for this renderer, it won't be used. + */ + @Override + public boolean displayable() { + return false; + } + + /* + protected void finalize() throws Throwable { + System.out.println("calling finalize"); + //document.close(); // do this in dispose instead? + } + */ + + + ////////////////////////////////////////////////////////////// + + + /* + public void endRecord() { + super.endRecord(); + dispose(); + } + + + public void endRaw() { + System.out.println("ending raw"); + super.endRaw(); + System.out.println("disposing"); + dispose(); + System.out.println("done"); + } + */ + + + ////////////////////////////////////////////////////////////// + + + /* + protected void rectImpl(float x1, float y1, float x2, float y2) { + //rect.setFrame(x1, y1, x2-x1, y2-y1); + //draw_shape(rect); + System.out.println("rect implements"); + g2.fillRect((int)x1, (int)y1, (int) (x2-x1), (int) (y2-y1)); + } + * + + /* + public void clear() { + g2.setColor(Color.red); + g2.fillRect(0, 0, width, height); + } + */ + + + ////////////////////////////////////////////////////////////// + + + /* + protected void imageImplAWT(java.awt.Image awtImage, + float x1, float y1, float x2, float y2, + int u1, int v1, int u2, int v2) { + pushMatrix(); + translate(x1, y1); + int awtImageWidth = awtImage.getWidth(null); + int awtImageHeight = awtImage.getHeight(null); + scale((x2 - x1) / (float)awtImageWidth, + (y2 - y1) / (float)awtImageHeight); + g2.drawImage(awtImage, + 0, 0, awtImageWidth, awtImageHeight, + u1, v1, u2, v2, null); + popMatrix(); + } + */ + + + ////////////////////////////////////////////////////////////// + + +// public void textFont(PFont which) { +// super.textFont(which); +// checkFont(); +// // Make sure a native version of the font is available. +//// if (textFont.getFont() == null) { +//// throw new RuntimeException("Use createFont() instead of loadFont() " + +//// "when drawing text using the PDF library."); +//// } +// // Make sure that this is a font that the PDF library can deal with. +//// if ((textMode != SHAPE) && !checkFont(which.getName())) { +//// System.err.println("Use PGraphicsPDF.listFonts() to get a list of available fonts."); +//// throw new RuntimeException("The font “" + which.getName() + "” cannot be used with PDF Export."); +//// } +// } + + +// /** +// * Change the textMode() to either SHAPE or MODEL. +// *
+// * This resets all renderer settings, and therefore must +// * be called before any other commands that set the fill() +// * or the textFont() or anything. Unlike other renderers, +// * use textMode() directly after the size() command. +// */ +// public void textMode(int mode) { +// if (textMode != mode) { +// if (mode == SHAPE) { +// textMode = SHAPE; +// g2.dispose(); +//// g2 = content.createGraphicsShapes(width, height); +// g2 = createGraphics(); +// } else if (mode == MODEL) { +// textMode = MODEL; +// g2.dispose(); +//// g2 = content.createGraphics(width, height, mapper); +// g2 = createGraphics(); +//// g2 = template.createGraphics(width, height, mapper); +// } else if (mode == SCREEN) { +// throw new RuntimeException("textMode(SCREEN) not supported with PDF"); +// } else { +// throw new RuntimeException("That textMode() does not exist"); +// } +// } +// } + + +// protected void textLineImpl(char buffer[], int start, int stop, +// float x, float y) { +// checkFont(); +// super.textLineImpl(buffer, start, stop, x, y); +// } + + + ////////////////////////////////////////////////////////////// + + + public void loadPixels() { + nope("loadPixels"); + } + + public void updatePixels() { + nope("updatePixels"); + } + + public void updatePixels(int x, int y, int c, int d) { + nope("updatePixels"); + } + + // + + public int get(int x, int y) { + nope("get"); + return 0; // not reached + } + + public PImage get(int x, int y, int c, int d) { + nope("get"); + return null; // not reached + } + + public PImage get() { + nope("get"); + return null; // not reached + } + + public void set(int x, int y, int argb) { + nope("set"); + } + + public void set(int x, int y, PImage image) { + nope("set"); + } + + // + + public void mask(int alpha[]) { + nope("mask"); + } + + public void mask(PImage alpha) { + nope("mask"); + } + + // + + public void filter(int kind) { + nope("filter"); + } + + public void filter(int kind, float param) { + nope("filter"); + } + + // + + public void copy(int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2) { + nope("copy"); + } + + public void copy(PImage src, + int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2) { + nope("copy"); + } + + // + + public void blend(int sx, int sy, int dx, int dy, int mode) { + nope("blend"); + } + + public void blend(PImage src, + int sx, int sy, int dx, int dy, int mode) { + nope("blend"); + } + + public void blend(int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + nope("blend"); + } + + public void blend(PImage src, + int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + nope("blend"); + } + + // + + public boolean save(String filename) { + nope("save"); + return false; + } + + + ////////////////////////////////////////////////////////////// + + +// /** +// * Add a directory that should be searched for font data. +// *
+// * On Mac OS X, the following directories are added by default: +// * +// * On Windows, all drive letters are searched for WINDOWS\Fonts +// * or WINNT\Fonts, any that exists is added. +// *

+// * On Linux or any other platform, you'll need to add the +// * directories by hand. (If there are actual standards here that we +// * can use as a starting point, please file a bug to make a note of it) +// */ +// public void addFonts(String directory) { +// mapper.insertDirectory(directory); +// } + + +// /** +// * Check whether the specified font can be used with the PDF library. +// * @param name name of the font +// * @return true if it's ok +// */ +// protected void checkFont() { +// Font awtFont = textFont.getFont(); +// if (awtFont == null) { // always need a native font or reference to it +// throw new RuntimeException("Use createFont() instead of loadFont() " + +// "when drawing text using the PDF library."); +// } else if (textMode != SHAPE) { +// if (textFont.isStream()) { +// throw new RuntimeException("Use textMode(SHAPE) with PDF when loading " + +// ".ttf and .otf files with createFont()."); +// } else if (mapper.getAliases().get(textFont.getName()) == null) { +// //System.out.println("alias for " + name + " = " + mapper.getAliases().get(name)); +//// System.err.println("Use PGraphicsPDF.listFonts() to get a list of " + +//// "fonts that can be used with PDF."); +//// throw new RuntimeException("The font “" + textFont.getName() + "” " + +//// "cannot be used with PDF Export."); +// if (textFont.getName().equals("Lucida Sans")) { +// throw new RuntimeException("Use textMode(SHAPE) with the default " + +// "font when exporting to PDF."); +// } else { +// throw new RuntimeException("Use textMode(SHAPE) with " + +// "“" + textFont.getName() + "” " + +// "when exporting to PDF."); +// } +// } +// } +// } + + +// /** +// * List the fonts known to the PDF renderer. This is like PFont.list(), +// * however not all those fonts are available by default. +// */ +// static public String[] listFonts() { +// if (fontList == null) { +// HashMap map = getMapper().getAliases(); +//// Set entries = map.entrySet(); +//// fontList = new String[entries.size()]; +// fontList = new String[map.size()]; +// int count = 0; +// for (Object entry : map.entrySet()) { +// fontList[count++] = (String) ((Map.Entry) entry).getKey(); +// } +//// Iterator it = entries.iterator(); +//// int count = 0; +//// while (it.hasNext()) { +//// Map.Entry entry = (Map.Entry) it.next(); +//// //System.out.println(entry.getKey() + "-->" + entry.getValue()); +//// fontList[count++] = (String) entry.getKey(); +//// } +// fontList = PApplet.sort(fontList); +// } +// return fontList; +// } + + + ////////////////////////////////////////////////////////////// + + + protected void nope(String function) { + throw new RuntimeException("No " + function + "() for PGraphicsSVG"); + } +}