Don't use JavaFX Canvas when running headless

This commit is contained in:
Anya Helene Bagge 2018-03-07 22:34:18 +01:00
parent 904d52872f
commit 858b4dfbc2
4 changed files with 69 additions and 43 deletions

View File

@ -222,7 +222,7 @@ public class ShapePainter implements IShape {
@Override @Override
public void draw(GraphicsContext context) { public void draw(GraphicsContext context) {
if (cmd != null) { if (cmd != null && context != null) {
if (fill != null) if (fill != null)
cmd.fill(context, this); cmd.fill(context, this);
if (stroke != null) if (stroke != null)
@ -238,7 +238,7 @@ public class ShapePainter implements IShape {
@Override @Override
public ShapePainter fill() { public ShapePainter fill() {
if (cmd != null) if (cmd != null && context != null)
cmd.fill(context, this); cmd.fill(context, this);
return this; return this;
} }
@ -288,7 +288,7 @@ public class ShapePainter implements IShape {
@Override @Override
public ShapePainter stroke() { public ShapePainter stroke() {
if (cmd != null) if (cmd != null && context != null)
cmd.stroke(context, this); cmd.stroke(context, this);
return this; return this;
} }

View File

@ -43,12 +43,10 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
private final Canvas canvas; private final Canvas canvas;
private boolean path = false; private boolean path = false;
public TurtlePainter(double width, double height, Canvas canvas) { public TurtlePainter(double width, double height) {
screen = null; this.screen = null;
if (canvas == null) this.canvas = null;
canvas = new Canvas(width, height); this.context = null;
this.canvas = canvas;
this.context = canvas.getGraphicsContext2D();
this.width = width; this.width = width;
this.height = height; this.height = height;
stateStack.add(new TurtleState()); stateStack.add(new TurtleState());
@ -57,6 +55,8 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
} }
public TurtlePainter(Screen screen, Canvas canvas) { public TurtlePainter(Screen screen, Canvas canvas) {
if (screen == null || canvas == null)
throw new IllegalArgumentException();
this.screen = screen; this.screen = screen;
this.canvas = canvas; this.canvas = canvas;
this.context = canvas.getGraphicsContext2D(); this.context = canvas.getGraphicsContext2D();
@ -82,26 +82,29 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
@Override @Override
public void clear() { public void clear() {
context.clearRect(0, 0, getWidth(), getHeight()); if (context != null)
context.clearRect(0, 0, getWidth(), getHeight());
} }
@Override @Override
public ITurtle curveTo(Point to, double startControl, double endAngle, double endControl) { public ITurtle curveTo(Point to, double startControl, double endAngle, double endControl) {
Point c1 = state.pos.move(state.dir, startControl); Point c1 = state.pos.move(state.dir, startControl);
Point c2 = to.move(Direction.fromDegrees(endAngle + 180), endControl); Point c2 = to.move(Direction.fromDegrees(endAngle + 180), endControl);
if (!path) { if (context != null) {
// context.save(); if (!path) {
context.setStroke(state.ink); // context.save();
context.setLineWidth(state.penSize); context.setStroke(state.ink);
context.beginPath(); context.setLineWidth(state.penSize);
context.moveTo(state.pos.getX(), state.pos.getY()); context.beginPath();
context.moveTo(state.pos.getX(), state.pos.getY());
}
context.bezierCurveTo(c1.getX(), c1.getY(), c2.getX(), c2.getY(), to.getX(), to.getY());
} }
context.bezierCurveTo(c1.getX(), c1.getY(), c2.getX(), c2.getY(), to.getX(), to.getY());
state.inDir = state.dir; state.inDir = state.dir;
state.pos = to; state.pos = to;
state.dir = Direction.fromDegrees(endAngle); state.dir = Direction.fromDegrees(endAngle);
if (!path) { if (!path && context != null) {
context.stroke(); context.stroke();
// context.restore(); // context.restore();
} }
@ -133,7 +136,7 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
@Override @Override
public ITurtle drawTo(Point to) { public ITurtle drawTo(Point to) {
if (path) { if (path && context != null) {
context.setStroke(state.ink); context.setStroke(state.ink);
context.setLineWidth(state.penSize); context.setLineWidth(state.penSize);
context.lineTo(to.getX(), to.getY()); context.lineTo(to.getX(), to.getY());
@ -178,7 +181,7 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
public ITurtle jump(double dist) { public ITurtle jump(double dist) {
state.inDir = state.dir; state.inDir = state.dir;
state.pos = state.pos.move(state.dir, dist); state.pos = state.pos.move(state.dir, dist);
if (path) if (path && context != null)
context.moveTo(state.pos.getX(), state.pos.getY()); context.moveTo(state.pos.getX(), state.pos.getY());
return this; return this;
} }
@ -187,7 +190,7 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
public ITurtle jump(Point relPos) { public ITurtle jump(Point relPos) {
// TODO: state.inDir = state.dir; // TODO: state.inDir = state.dir;
state.pos = state.pos.move(relPos); state.pos = state.pos.move(relPos);
if (path) if (path && context != null)
context.moveTo(state.pos.getX(), state.pos.getY()); context.moveTo(state.pos.getX(), state.pos.getY());
return this; return this;
@ -221,11 +224,13 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
@Override @Override
public ITurtle line(Point to) { public ITurtle line(Point to) {
// context.save(); if (context != null) {
context.setStroke(state.ink); // context.save();
context.setLineWidth(state.penSize); context.setStroke(state.ink);
context.strokeLine(state.pos.getX(), state.pos.getY(), to.getX(), to.getY()); context.setLineWidth(state.penSize);
// context.restore(); context.strokeLine(state.pos.getX(), state.pos.getY(), to.getX(), to.getY());
// context.restore();
}
return this; return this;
} }
@ -314,8 +319,7 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
@Override @Override
public ITurtle turtle() { public ITurtle turtle() {
TurtlePainter painter = screen != null ? new TurtlePainter(screen, canvas) TurtlePainter painter = screen != null ? new TurtlePainter(screen, canvas) : new TurtlePainter(width, height);
: new TurtlePainter(width, height, canvas);
painter.stateStack.set(0, new TurtleState(state)); painter.stateStack.set(0, new TurtleState(state));
return painter; return painter;
} }
@ -324,16 +328,19 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
if (path) if (path)
throw new IllegalStateException("beginPath() after beginPath()"); throw new IllegalStateException("beginPath() after beginPath()");
path = true; path = true;
context.setStroke(state.ink); if (context != null) {
context.beginPath(); context.setStroke(state.ink);
context.moveTo(state.pos.getX(), state.pos.getY()); context.beginPath();
context.moveTo(state.pos.getX(), state.pos.getY());
}
return this; return this;
} }
public ITurtle closePath() { public ITurtle closePath() {
if (!path) if (!path)
throw new IllegalStateException("closePath() without beginPath()"); throw new IllegalStateException("closePath() without beginPath()");
context.closePath(); if (context != null)
context.closePath();
return this; return this;
} }
@ -341,7 +348,8 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
if (!path) if (!path)
throw new IllegalStateException("endPath() without beginPath()"); throw new IllegalStateException("endPath() without beginPath()");
path = false; path = false;
context.stroke(); if (context != null)
context.stroke();
return this; return this;
} }
@ -349,10 +357,12 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
if (!path) if (!path)
throw new IllegalStateException("fillPath() without beginPath()"); throw new IllegalStateException("fillPath() without beginPath()");
path = false; path = false;
context.save(); if (context != null) {
context.setFill(state.ink); context.save();
context.fill(); context.setFill(state.ink);
context.restore(); context.fill();
context.restore();
}
return this; return this;
} }

View File

@ -100,13 +100,25 @@ public class Printer implements IPaintLayer {
private int csiMode = 0; private int csiMode = 0;
private final double width;
private final double height;
public Printer(double width, double height) { public Printer(double width, double height) {
this(null, new Canvas(width, height)); this.screen = null;
this.textPage = null;
this.width = width;
this.height = height;
for (int i = 0; i < TextMode.PAGE_HEIGHT_MAX; i++) {
lineBuffer.add(new Char[TextMode.LINE_WIDTH_MAX]);
}
resetFull();
} }
public Printer(Screen screen, Canvas page) { public Printer(Screen screen, Canvas page) {
this.screen = screen; this.screen = screen;
this.textPage = page; this.textPage = page;
this.width = page.getWidth();
this.height = page.getHeight();
for (int i = 0; i < TextMode.PAGE_HEIGHT_MAX; i++) { for (int i = 0; i < TextMode.PAGE_HEIGHT_MAX; i++) {
lineBuffer.add(new Char[TextMode.LINE_WIDTH_MAX]); lineBuffer.add(new Char[TextMode.LINE_WIDTH_MAX]);
} }
@ -126,15 +138,17 @@ public class Printer implements IPaintLayer {
moveTo(leftMargin, y + 1); moveTo(leftMargin, y + 1);
break; break;
case "\f": case "\f":
GraphicsContext context = textPage.getGraphicsContext2D();
moveTo(leftMargin, topMargin); moveTo(leftMargin, topMargin);
for (Char[] line : lineBuffer) for (Char[] line : lineBuffer)
Arrays.fill(line, null); Arrays.fill(line, null);
if(textPage != null) {
GraphicsContext context = textPage.getGraphicsContext2D();
if (background != null && background != Color.TRANSPARENT) { if (background != null && background != Color.TRANSPARENT) {
context.setFill(background); context.setFill(background);
context.fillRect(0.0, 0.0, textPage.getWidth(), textPage.getHeight()); context.fillRect(0.0, 0.0, textPage.getWidth(), textPage.getHeight());
} else } else
context.clearRect(0.0, 0.0, textPage.getWidth(), textPage.getHeight()); context.clearRect(0.0, 0.0, textPage.getWidth(), textPage.getHeight());
}
break; break;
case "\b": case "\b":
moveHoriz(-1); moveHoriz(-1);
@ -286,7 +300,7 @@ public class Printer implements IPaintLayer {
} }
private void drawChar(int x, int y, Char c) { private void drawChar(int x, int y, Char c) {
if (c != null) { if (c != null && textPage != null) {
GraphicsContext context = textPage.getGraphicsContext2D(); GraphicsContext context = textPage.getGraphicsContext2D();
context.setFill(c.fill); context.setFill(c.fill);
@ -502,6 +516,8 @@ public class Printer implements IPaintLayer {
* "ms/char", "mode", "indir", "inv", "fake"); for (int m = -1; m < 8; m++) { * "ms/char", "mode", "indir", "inv", "fake"); for (int m = -1; m < 8; m++) {
* long t0 = System.currentTimeMillis(); int n = 0; * long t0 = System.currentTimeMillis(); int n = 0;
*/ */
if(textPage == null)
return;
GraphicsContext context = textPage.getGraphicsContext2D(); GraphicsContext context = textPage.getGraphicsContext2D();
if (background != null && background != Color.TRANSPARENT) { if (background != null && background != Color.TRANSPARENT) {
@ -720,12 +736,12 @@ public class Printer implements IPaintLayer {
@Override @Override
public double getWidth() { public double getWidth() {
return textPage.getWidth(); return width;
} }
@Override @Override
public double getHeight() { public double getHeight() {
return textPage.getHeight(); return height;
} }
} }

View File

@ -91,7 +91,7 @@ public class Game implements IGame {
public Game(String mapString) { public Game(String mapString) {
printer = new Printer(1280, 720); printer = new Printer(1280, 720);
painter = new TurtlePainter(1280, 720, null); painter = new TurtlePainter(1280, 720);
IGrid<String> inputGrid = MapReader.readString(mapString); IGrid<String> inputGrid = MapReader.readString(mapString);
this.map = new GameMap(inputGrid.getArea()); this.map = new GameMap(inputGrid.getArea());
for (ILocation loc : inputGrid.locations()) { for (ILocation loc : inputGrid.locations()) {