rework non-visible surface handling, fix size() parser

This commit is contained in:
Ben Fry
2015-05-15 16:00:35 -04:00
parent 79ba41cede
commit c37e9dc81e
6 changed files with 144 additions and 76 deletions
+25 -12
View File
@@ -44,6 +44,7 @@ import java.awt.image.BufferedImage;
// used by loadImage() functions
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
@@ -1489,6 +1490,7 @@ public class PApplet implements PConstants {
size(w, h, sketchRenderer(), null);
}
/**
* @param renderer Either P2D, P3D, or PDF
*/
@@ -1496,16 +1498,26 @@ public class PApplet implements PConstants {
size(w, h, renderer, null);
}
/**
* @nowebref
*/
/**
* @nowebref
*/
public void size(final int w, final int h, String renderer, String path) {
if (!renderer.equals(sketchRenderer())) {
System.err.println("Because you're not running from the PDE, add this to your code:");
System.err.println("public String sketchRenderer() {");
System.err.println(" return \"" + renderer + "\";");
System.err.println("}");
throw new RuntimeException("The sketchRenderer() method is not implemented.");
if (external) {
// The PDE should have parsed it, but something still went wrong
final String msg =
String.format("Something bad happened when calling " +
"size(%d, %d, %s, %s)", w, h, renderer, path);
throw new RuntimeException(msg);
} else {
System.err.println("Because you're not running from the PDE, add this to your code:");
System.err.println("public String sketchRenderer() {");
System.err.println(" return \"" + renderer + "\";");
System.err.println("}");
throw new RuntimeException("The sketchRenderer() method is not implemented.");
}
}
surface.setSize(w, h);
g.setPath(path); // finally, a path
@@ -1700,6 +1712,7 @@ public class PApplet implements PConstants {
pg.setParent(this);
pg.setPrimary(primary);
System.out.println("path is " + path);
if (path != null) {
pg.setPath(path);
}
@@ -1770,7 +1783,8 @@ public class PApplet implements PConstants {
/** Create default renderer, likely to be resized, but needed for surface init. */
protected PGraphics createPrimaryGraphics() {
return makeGraphics(sketchWidth(), sketchHeight(), sketchRenderer(), null, true);
return makeGraphics(sketchWidth(), sketchHeight(),
sketchRenderer(), sketchOutputPath(), true);
}
@@ -9643,9 +9657,8 @@ public class PApplet implements PConstants {
surface.initFrame(this, backgroundColor, displayIndex, present, spanDisplays);
surface.setTitle(getClass().getName());
//frame.setTitle(getClass().getName());
// } else {
// // TODO necessary?
// surface.initOffscreen(this);
} else {
surface.initOffscreen(this); // for PDF, PSurfaceNone, and friends
}
init();
+2 -2
View File
@@ -27,8 +27,6 @@ package processing.core;
import java.awt.Cursor;
import java.awt.event.KeyEvent;
import processing.data.StringList;
/**
* Numbers shared throughout processing.core.
@@ -48,6 +46,7 @@ public interface PConstants {
// renderers known to processing.core
/*
// List of renderers used inside PdePreprocessor
static final StringList rendererList = new StringList(new String[] {
"JAVA2D", "JAVA2D_2X",
@@ -56,6 +55,7 @@ public interface PConstants {
"LWJGL.P2D", "LWJGL.P3D", // hmm
"PDF" // no DXF because that's only for beginRaw()
});
*/
static final String JAVA2D = "processing.core.PGraphicsJava2D";
static final String JAVA2D_2X = "processing.core.PGraphicsJava2D2X";
+4 -3
View File
@@ -46,7 +46,7 @@ public class PSurfaceNone implements PSurface {
@Override
public void initOffscreen(PApplet sketch) {
// TODO Auto-generated method stub
this.sketch = sketch;
}
@@ -57,8 +57,9 @@ public class PSurfaceNone implements PSurface {
@Override
public void initFrame(PApplet sketch, int backgroundColor,
int deviceIndex, boolean fullScreen,
boolean spanDisplays) {
int deviceIndex, boolean fullScreen,
boolean spanDisplays) {
this.sketch = sketch;
}
+6 -2
View File
@@ -38,13 +38,17 @@ _ implement frameRate()
_ implement external messages (moving the window)
opengl
X deal with some performance issues
X https://github.com/processing/processing/issues/3210
X Can't run sketches with offscreen PGraphics
X https://github.com/processing/processing/issues/3259
_ Merge glw code into the OpenGL library
_ https://github.com/processing/processing/issues/3284
_ why is createShape() implemented 4x (for P2D, P3D, and 2x versions)?
_ shouldn't be static, run it from the renderer, that's point of createXxx()
_ when did setPath() sneak into PShape? API is nothing like anything else
_ public createShape() method that takes another shape as param?
_ should just be the constructor doing this, or copy()
_ drawing 100k lines is slow (example from Reas)
_ figure out what the bottleneck is here
high priority
@@ -118,12 +118,14 @@ public class PGraphicsPDF extends PGraphicsJava2D {
if (document == null) {
document = new Document(new Rectangle(width, height));
boolean missingPath = false;
try {
if (file != null) {
//BufferedOutputStream output = new BufferedOutputStream(stream, 16384);
output = new BufferedOutputStream(new FileOutputStream(file), 16384);
} else if (output == null) {
missingPath = true;
throw new RuntimeException("PGraphicsPDF requires a path " +
"for the location of the output file.");
}
@@ -132,25 +134,26 @@ public class PGraphicsPDF extends PGraphicsJava2D {
content = writer.getDirectContent();
// template = content.createTemplate(width, height);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Problem saving the PDF file.");
} catch (RuntimeException re) {
if (missingPath) {
throw re; // don't re-package our own error
} else {
throw new RuntimeException("Problem saving the PDF file.", re);
}
} catch (FileNotFoundException fnfe) {
throw new RuntimeException("Can't save the PDF file to " + path, fnfe);
} catch (DocumentException de) {
throw new RuntimeException("Error inside the PDF library.", de);
}
// System.out.println("beginDraw fonts " + (System.currentTimeMillis() - t));
// g2 = content.createGraphics(width, height, getMapper());
// if (textMode == SHAPE) {
g2 = content.createGraphicsShapes(width, height);
// } else if (textMode == MODEL) {
// g2 = content.createGraphics(width, height, getMapper());
// }
// g2 = createGraphics();
// g2 = template.createGraphics(width, height, mapper);
}
// System.out.println("beginDraw " + (System.currentTimeMillis() - t0));
// super in Java2D now creates an image buffer, don't do that
// super.beginDraw();
//super.beginDraw();
checkSettings();
resetMatrix(); // reset model matrix
vertexCount = 0;
@@ -4,7 +4,7 @@
PdePreprocessor - wrapper for default ANTLR-generated parser
Part of the Processing project - http://processing.org
Copyright (c) 2004-12 Ben Fry and Casey Reas
Copyright (c) 2004-15 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
ANTLR-generated parser and several supporting classes written
@@ -36,7 +36,7 @@ import processing.app.Base;
import processing.app.Preferences;
import processing.app.SketchException;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.data.StringList;
import processing.mode.java.preproc.PdeLexer;
import processing.mode.java.preproc.PdeRecognizer;
import processing.mode.java.preproc.PdeTokenTypes;
@@ -167,12 +167,13 @@ public class PdePreprocessor {
* in the sketch, which is the case especially for anyone who is cutting
* and pasting from the reference.
*/
public static final String SIZE_REGEX =
"(?:^|\\s|;)size\\s*\\(\\s*([^\\s,]+)\\s*,\\s*([^\\s,\\)]+)\\s*,?\\s*([^\\)]*)\\s*\\)\\s*\\;";
//"(?:^|\\s|;)size\\s*\\(\\s*(\\S+)\\s*,\\s*([^\\s,\\)]+),?\\s*([^\\)]*)\\s*\\)\\s*\\;";
// public static final String SIZE_REGEX =
// "(?:^|\\s|;)size\\s*\\(\\s*([^\\s,]+)\\s*,\\s*([^\\s,\\)]+)\\s*,?\\s*([^\\)]*)\\s*\\)\\s*\\;";
static private final String SIZE_CONTENTS_REGEX =
"(?:^|\\s|;)size\\s*\\(([^\\)]+)\\)\\s*\\;";
private static final Pattern PUBLIC_CLASS =
static private final Pattern PUBLIC_CLASS =
Pattern.compile("(^|;)\\s*public\\s+class\\s+\\S+\\s+extends\\s+PApplet", Pattern.MULTILINE);
// Can't only match any 'public class', needs to be a PApplet
// http://code.google.com/p/processing/issues/detail?id=551
@@ -201,6 +202,7 @@ public class PdePreprocessor {
public String[] initSketchSize(String code, boolean sizeWarning) throws SketchException {
String[] info = parseSketchSize(code, sizeWarning);
PApplet.printArray(info);
if (info != null) {
sizeStatement = info[0];
sketchWidth = info[1];
@@ -211,6 +213,44 @@ public class PdePreprocessor {
}
// break on commas, except those inside quotes, e.g.:
// size(300, 200, PDF, "output,weirdname.pdf");
// no handling for escaped (\") quotes
static private StringList breakCommas(String contents) {
StringList outgoing = new StringList();
boolean insideQuote = false;
// The current word being read
StringBuilder current = new StringBuilder();
char[] chars = contents.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (insideQuote) {
current.append(c);
if (c == '\"') {
insideQuote = false;
}
} else {
if (c == ',') {
if (current.length() != 0) {
outgoing.append(current.toString());
current.setLength(0);
}
} else {
current.append(c);
if (c == '\"') {
insideQuote = true;
}
}
}
}
if (current.length() != 0) {
outgoing.append(current.toString());
}
return outgoing;
}
/**
* Parse a chunk of code and extract the size() command and its contents.
* @param code Usually the code from the main tab in the sketch
@@ -225,15 +265,29 @@ public class PdePreprocessor {
// String scrubbed = scrubComments(sketch.getCode(0).getProgram());
// String[] matches = PApplet.match(scrubbed, SIZE_REGEX);
String[] matches = PApplet.match(scrubComments(code), SIZE_REGEX);
// String[] matches = PApplet.match(scrubComments(code), SIZE_REGEX);
// Get everything inside the parens for the size() method
String[] contents = PApplet.match(scrubComments(code), SIZE_CONTENTS_REGEX);
if (contents != null) {
//String[] matches = split on commas, but not commas inside quotes
StringList args = breakCommas(contents[1]);
String width = args.get(0);
String height = args.get(1);
String renderer = (args.size() >= 3) ? args.get(2) : null;
String path = (args.size() >= 4) ? args.get(3) : null;
if (matches != null) {
boolean badSize = false;
if (matches[1].equals("screenWidth") ||
matches[1].equals("screenHeight") ||
matches[2].equals("screenWidth") ||
matches[2].equals("screenHeight")) {
// Trying to remember why we wanted to allow people to use displayWidth
// as the height or displayHeight as the width, but maybe it's for
// making a square sketch window? Not going to
if (width.equals("screenWidth") ||
width.equals("screenHeight") ||
height.equals("screenHeight") ||
height.equals("screenWidth")) {
final String message =
"The screenWidth and screenHeight variables\n" +
"are named displayWidth and displayHeight\n" +
@@ -242,14 +296,14 @@ public class PdePreprocessor {
return null;
}
if (!matches[1].equals("displayWidth") &&
!matches[1].equals("displayHeight") &&
PApplet.parseInt(matches[1], -1) == -1) {
if (!width.equals("displayWidth") &&
!width.equals("displayHeight") &&
PApplet.parseInt(width, -1) == -1) {
badSize = true;
}
if (!matches[2].equals("displayWidth") &&
!matches[2].equals("displayHeight") &&
PApplet.parseInt(matches[2], -1) == -1) {
if (!height.equals("displayWidth") &&
!height.equals("displayHeight") &&
PApplet.parseInt(height, -1) == -1) {
badSize = true;
}
@@ -266,15 +320,24 @@ public class PdePreprocessor {
}
// Remove additional space 'round the renderer
matches[3] = matches[3].trim();
// if the renderer entry is empty, set it to null
if (matches[3].length() == 0) {
matches[3] = null;
if (renderer != null) {
renderer = renderer.trim();
if (renderer.length() == 0) { // if empty, set null
renderer = null;
}
}
return matches;
// Same for the file name
if (path != null) {
path = path.trim();
if (path.length() == 0) {
path = null;
}
}
return new String[] { contents[0], width, height, renderer, path };
}
return new String[] { null, null, null, null }; // not an error, just empty
// not an error, just no size() specified
return new String[] { null, null, null, null, null };
}
@@ -888,25 +951,9 @@ public class PdePreprocessor {
}
if (sketchRenderer != null && !hasMethod("sketchRenderer")) {
// Only include if it's a known renderer (otherwise it might be a variable)
if (PConstants.rendererList.hasValue(sketchRenderer)) {
/*
}
if (sketchRenderer.equals("P2D") ||
sketchRenderer.equals("P2D_2X") ||
sketchRenderer.equals("P3D") ||
sketchRenderer.equals("P3D_3X") ||
sketchRenderer.equals("OPENGL") ||
sketchRenderer.equals("JAVA2D") ||
sketchRenderer.equals("JAVA2D_2X") ||
sketchRenderer.equals("E2D") ||
sketchRenderer.equals("FX2D") ||
sketchRenderer.equals("FX2D_2X") ||
sketchRenderer.equals("PDF") ||
sketchRenderer.equals("LWJGL.P2D") ||
sketchRenderer.equals("LWJGL.P3D")) {
*/
out.println(indent + "public String sketchRenderer() { return " + sketchRenderer + "; }");
}
//if (PConstants.rendererList.hasValue(sketchRenderer)) {
out.println(indent + "public String sketchRenderer() { return " + sketchRenderer + "; }");
//}
}
if (!hasMethod("main")) {