1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-22 04:55:10 +00:00

refactor: remove unused logo dead code

This commit is contained in:
Arnaud Roques 2023-10-22 11:28:29 +02:00
parent 9a75a9c577
commit 8f5c3379ed
7 changed files with 2 additions and 846 deletions

View File

@ -3,4 +3,5 @@
This document catalogs code that was previously part of PlantUML but has since been deprecated and removed due to its lack of use. This document catalogs code that was previously part of PlantUML but has since been deprecated and removed due to its lack of use.
It serves as a historical reference to ensure we remember and understand past decisions. It serves as a historical reference to ensure we remember and understand past decisions.
- [logo](https://github.com/plantuml/plantuml/tree/v1.2023.12/src/net/sourceforge/plantuml/logo) - [logo language](https://github.com/plantuml/plantuml/tree/v1.2023.12/src/net/sourceforge/plantuml/logo)
- [mjpeg export](https://github.com/plantuml/plantuml/tree/v1.2023.12/src/net/sourceforge/plantuml/mjpeg)

View File

@ -1,174 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML 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 General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.logo;
import java.util.HashMap;
import java.util.Map;
class LogoScanner {
// ::remove folder when __HAXE__
// ::remove folder when __CORE__
// ::remove folder when __MIT__ or __EPL__ or __BSD__ or __ASL__ or __LGPL__
final private Map<String, Integer> keywordTable = new HashMap<String, Integer>();
private char sourceString[];
private int sourceLength;
private int i;
public LogoScanner() {
keywordTable.put("forward", LogoToken.FORWARD);
keywordTable.put("fd", LogoToken.FORWARD);
keywordTable.put("back", LogoToken.BACK);
keywordTable.put("bk", LogoToken.BACK);
keywordTable.put("right", LogoToken.RIGHT);
keywordTable.put("rt", LogoToken.RIGHT);
keywordTable.put("left", LogoToken.LEFT);
keywordTable.put("lt", LogoToken.LEFT);
keywordTable.put("penup", LogoToken.PENUP);
keywordTable.put("pu", LogoToken.PENUP);
keywordTable.put("pendown", LogoToken.PENDOWN);
keywordTable.put("pd", LogoToken.PENDOWN);
keywordTable.put("hideturtle", LogoToken.HIDETURTLE);
keywordTable.put("ht", LogoToken.HIDETURTLE);
keywordTable.put("showturtle", LogoToken.SHOWTURTLE);
keywordTable.put("st", LogoToken.SHOWTURTLE);
keywordTable.put("clearscreen", LogoToken.CLEARSCREEN);
keywordTable.put("cs", LogoToken.CLEARSCREEN);
keywordTable.put("repeat", LogoToken.REPEAT);
keywordTable.put("rep", LogoToken.REPEAT);
keywordTable.put("to", LogoToken.TO);
keywordTable.put("setpc", LogoToken.SETPC);
keywordTable.put("pc", LogoToken.SETPC);
}
public int getPosition() {
return i;
}
public void setPosition(int newPosition) {
if (i >= 0 && i <= sourceLength) {
i = newPosition;
} else {
i = sourceLength;
}
}
public void setSourceString(String newSourceString) {
sourceLength = newSourceString.length();
sourceString = newSourceString.concat("\0").toCharArray();
i = 0;
}
public String getSourceString() {
return new String(sourceString);
}
public String getRestAsString() {
skipWhitespace();
final String rest = new String(sourceString, i, sourceLength - i + 1);
i = sourceLength;
return rest;
}
void skipWhitespace() {
char c;
do {
c = sourceString[i++];
} while (c == ' ' || c == '\t');
i--;
}
public LogoToken getToken() {
final LogoToken token = new LogoToken();
final StringBuilder lexeme = new StringBuilder();
if (i >= sourceLength) {
token.kind = LogoToken.END_OF_INPUT;
return token;
}
// Skip whitespace.
skipWhitespace();
char c = sourceString[i++];
// Now figure out what kind of token we've got.
if (c == '[' || c == ']') {
token.kind = c;
token.lexeme = String.valueOf(c);
} else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
do {
lexeme.append(c);
c = sourceString[i++];
} while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
i--;
token.lexeme = lexeme.toString();
token.kind = LogoToken.IDENTIFIER;
final Integer keyword = keywordTable.get(token.lexeme);
if (keyword != null) {
token.kind = keyword;
}
} else if (c >= '0' && c <= '9') {
do {
lexeme.append(c);
c = sourceString[i++];
} while (c >= '0' && c <= '9');
boolean hasDecimalPart = false;
if (c == '.') {
do {
lexeme.append(c);
c = sourceString[i++];
} while (c >= '0' && c <= '9');
hasDecimalPart = true;
}
i--;
token.lexeme = lexeme.toString();
token.value = Float.parseFloat(token.lexeme);
if (hasDecimalPart) {
token.kind = LogoToken.FLOAT;
} else {
token.kind = LogoToken.INTEGER;
token.intValue = Integer.parseInt(token.lexeme);
}
} else if (c == 0) {
i--;
token.kind = LogoToken.END_OF_INPUT;
} else {
i--;
token.kind = LogoToken.INVALID_TOKEN;
}
return token;
}
}

View File

@ -1,62 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML 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 General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.logo;
class LogoToken {
public final static int END_OF_INPUT = 256;
public final static int INVALID_TOKEN = 257;
public final static int IDENTIFIER = 258;
public final static int FLOAT = 259;
public final static int INTEGER = 270;
public final static int FORWARD = 260;
public final static int BACK = 261;
public final static int LEFT = 262;
public final static int RIGHT = 263;
public final static int PENUP = 264;
public final static int PENDOWN = 265;
public final static int HIDETURTLE = 266;
public final static int SHOWTURTLE = 267;
public final static int CLEARSCREEN = 268;
public final static int REPEAT = 269;
public final static int TO = 271;
public final static int SETPC = 272;
public int kind;
public String lexeme;
public float value;
public int intValue;
}

View File

@ -1,109 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML 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 General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.logo;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.EmptyImageBuilder;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.core.UmlSource;
import net.sourceforge.plantuml.klimt.color.ColorMapper;
import net.sourceforge.plantuml.klimt.color.HColors;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.drawing.g2d.UGraphicG2d;
import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.png.PngIO;
public class PSystemLogo extends AbstractPSystem {
private final List<String> lines = new ArrayList<>();
public PSystemLogo(UmlSource source) {
super(source);
}
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat)
throws IOException {
final int width = 640;
final int height = 480;
final StringBounder stringBounder = FileFormat.PNG.getDefaultStringBounder();
final EmptyImageBuilder builder = new EmptyImageBuilder(fileFormat.getWatermark(), width, height, Color.WHITE,
stringBounder);
final BufferedImage im = builder.getBufferedImage();
final UGraphic ug = new UGraphicG2d(HColors.WHITE, ColorMapper.IDENTITY, stringBounder, builder.getGraphics2D(),
1.0, FileFormat.PNG);
((UGraphicG2d) ug).setBufferedImage(im);
final TurtleGraphicsPane turtleGraphicsPane = new TurtleGraphicsPane(width, height);
final TinyJavaLogo tinyJavaLogo = new TinyJavaLogo(turtleGraphicsPane);
for (String line : lines) {
tinyJavaLogo.doCommandLine(line);
}
turtleGraphicsPane.paint(ug);
PngIO.write(im, ColorMapper.IDENTITY, os, null, 96);
return new ImageDataSimple(im.getWidth(), im.getHeight());
}
// private GraphicStrings getGraphicStrings() throws IOException {
// final UFont font = new UFont("SansSerif", Font.PLAIN, 12);
// final GraphicStrings result = new GraphicStrings(strings, font,
// HtmlColorUtils.BLACK, HtmlColorUtils.WHITE,
// image,
// GraphicPosition.BOTTOM, false);
// result.setMinWidth(200);
// return result;
// }
public DiagramDescription getDescription() {
return new DiagramDescription("(Logo)");
}
public void doCommandLine(String line) {
lines.add(line);
}
}

View File

@ -1,60 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML 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 General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.logo;
import net.sourceforge.plantuml.command.PSystemBasicFactory;
import net.sourceforge.plantuml.core.UmlSource;
public class PSystemLogoFactory extends PSystemBasicFactory<PSystemLogo> {
@Override
public PSystemLogo initDiagram(UmlSource source, String startLine) {
return null;
}
@Override
public PSystemLogo executeLine(UmlSource source, PSystemLogo system, String line) {
if (system == null && line.equalsIgnoreCase("logo")) {
return new PSystemLogo(source);
}
if (system == null) {
return null;
}
system.doCommandLine(line);
return system;
}
}

View File

@ -1,229 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML 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 General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.logo;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.color.HColorSet;
public class TinyJavaLogo {
private final LogoScanner scanner = new LogoScanner();
private final TurtleGraphicsPane turtleGraphicsPane;
private final Map<String, String> dictionary = new HashMap<String, String>();
private HColor penColor;
public TinyJavaLogo(TurtleGraphicsPane turtleGraphicsPane) {
this.turtleGraphicsPane = turtleGraphicsPane;
}
private void message(String messageText) {
// turtleGraphicsPane.message(messageText);
}
private void error(String messageText) {
turtleGraphicsPane.message("Error: " + messageText);
}
private void parseCommandBlock(int nestLevel) {
String commandName;
String code;
LogoToken token = scanner.getToken();
while (token.kind != LogoToken.END_OF_INPUT && token.kind != LogoToken.INVALID_TOKEN) {
switch (token.kind) {
case LogoToken.FORWARD:
token = scanner.getToken();
if (token.kind == LogoToken.FLOAT || token.kind == LogoToken.INTEGER) {
turtleGraphicsPane.forward(token.value);
token = scanner.getToken();
} else {
error("FORWARD requires distance");
return;
}
break;
case LogoToken.BACK:
token = scanner.getToken();
if (token.kind == LogoToken.FLOAT || token.kind == LogoToken.INTEGER) {
turtleGraphicsPane.back(token.value);
token = scanner.getToken();
} else {
error("BACK requires distance");
return;
}
break;
case LogoToken.LEFT:
token = scanner.getToken();
if (token.kind == LogoToken.FLOAT || token.kind == LogoToken.INTEGER) {
turtleGraphicsPane.left(token.value);
token = scanner.getToken();
} else {
error("LEFT requires turn angle");
return;
}
break;
case LogoToken.RIGHT:
token = scanner.getToken();
if (token.kind == LogoToken.FLOAT || token.kind == LogoToken.INTEGER) {
turtleGraphicsPane.right(token.value);
token = scanner.getToken();
} else {
error("RIGHT requires turn angle");
return;
}
break;
case LogoToken.PENUP:
turtleGraphicsPane.penUp();
token = scanner.getToken();
break;
case LogoToken.PENDOWN:
turtleGraphicsPane.penDown();
token = scanner.getToken();
break;
case LogoToken.HIDETURTLE:
turtleGraphicsPane.hideTurtle();
token = scanner.getToken();
break;
case LogoToken.SHOWTURTLE:
turtleGraphicsPane.showTurtle();
token = scanner.getToken();
break;
case LogoToken.CLEARSCREEN:
turtleGraphicsPane.clearScreen();
token = scanner.getToken();
break;
case LogoToken.REPEAT:
token = scanner.getToken();
if (token.kind != LogoToken.INTEGER) {
error("REPEAT requires positive integer count");
return;
}
int count = token.intValue;
token = scanner.getToken();
if (token.kind != '[') {
error("REPEAT requires block in []");
return;
}
final int blockStart = scanner.getPosition();
while (count-- > 0) {
scanner.setPosition(blockStart);
parseCommandBlock(nestLevel + 1);
}
token = scanner.getToken();
break;
case LogoToken.TO:
token = scanner.getToken();
if (token.kind != LogoToken.IDENTIFIER) {
error("TO requires name for new definition");
return;
}
commandName = token.lexeme;
if (dictionary.get(commandName) == null) {
message("Defining new command " + commandName);
} else {
message("Redefining command " + commandName);
}
code = scanner.getRestAsString();
dictionary.put(commandName, code);
token = scanner.getToken();
break;
case LogoToken.IDENTIFIER:
commandName = token.lexeme;
code = dictionary.get(commandName);
if (code == null) {
error("Undefined command " + commandName);
return;
}
final String savedCommand = scanner.getSourceString();
final int savedPosition = scanner.getPosition();
scanner.setSourceString(code);
parseCommandBlock(0);
scanner.setSourceString(savedCommand);
scanner.setPosition(savedPosition);
token = scanner.getToken();
break;
case LogoToken.SETPC:
token = scanner.getToken();
String s = token.lexeme;
final HColor newPenColor = s == null ? null : HColorSet.instance().getColorOrWhite(s);
if (newPenColor == null) {
error("Unrecognized color name");
return;
}
penColor = newPenColor;
turtleGraphicsPane.setPenColor(penColor);
token = scanner.getToken();
break;
case '[':
token = scanner.getToken();
break;
case ']':
if (nestLevel == 0) {
error("] without matching [");
token = scanner.getToken();
return;
}
return;
default:
error("Unrecognized symbol in input");
return;
}
}
}
public void doCommandLine(String commandLine) {
message(commandLine);
scanner.setSourceString(commandLine);
parseCommandBlock(0);
}
}

View File

@ -1,211 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML 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 General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.logo;
import java.awt.Font;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.color.HColorSet;
import net.sourceforge.plantuml.klimt.color.HColors;
import net.sourceforge.plantuml.klimt.creole.Display;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
import net.sourceforge.plantuml.klimt.font.UFont;
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
import net.sourceforge.plantuml.klimt.geom.XDimension2D;
import net.sourceforge.plantuml.klimt.shape.TextBlock;
import net.sourceforge.plantuml.klimt.shape.ULine;
import net.sourceforge.plantuml.klimt.shape.UPolygon;
import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
class TurtleGraphicsPane {
final private double width;
final private double height;
private double x;
private double y;
private double turtleDirection = 90;
private boolean penIsDown = true;
private boolean showTurtle = true;
private HColor penColor = HColors.BLACK;
private List<Rectangle2D.Double> lines = new ArrayList<Rectangle2D.Double>();
private List<HColor> colors = new ArrayList<>();
private String message;
public TurtleGraphicsPane(int width, int height) {
this.width = width;
this.height = height;
clearScreen();
}
public void clearScreen() {
x = width / 2;
y = -height / 2;
turtleDirection = 90;
lines.clear();
colors.clear();
}
private double dtor(double degrees) {
return degrees * Math.PI / 180.0;
}
private void drawTurtle(UGraphic ug) {
if (showTurtle == false) {
return;
}
final UPolygon poly = new UPolygon();
double size = 2;
double deltax = 4.5 * size;
poly.addPoint(0 * size - deltax, 0);
poly.addPoint(0 * size - deltax, -2 * size);
poly.addPoint(1 * size - deltax, -2 * size);
poly.addPoint(1 * size - deltax, -4 * size);
poly.addPoint(2 * size - deltax, -4 * size);
poly.addPoint(2 * size - deltax, -6 * size);
poly.addPoint(3 * size - deltax, -6 * size);
poly.addPoint(3 * size - deltax, -8 * size);
poly.addPoint(4 * size - deltax, -8 * size);
poly.addPoint(4 * size - deltax, -9 * size);
poly.addPoint(5 * size - deltax, -9 * size);
poly.addPoint(5 * size - deltax, -8 * size);
poly.addPoint(6 * size - deltax, -8 * size);
poly.addPoint(6 * size - deltax, -6 * size);
poly.addPoint(7 * size - deltax, -6 * size);
poly.addPoint(7 * size - deltax, -4 * size);
poly.addPoint(8 * size - deltax, -4 * size);
poly.addPoint(8 * size - deltax, -2 * size);
poly.addPoint(9 * size - deltax, -2 * size);
poly.addPoint(9 * size - deltax, 0);
poly.addPoint(0 * size - deltax, 0);
final double angle = -dtor(turtleDirection - 90);
poly.rotate(angle);
// ug.setAntiAliasing(false);
final HColorSet htmlColorSet = HColorSet.instance();
final HColor turtleColor1 = htmlColorSet.getColorOrWhite("OliveDrab");
final HColor turtleColor2 = htmlColorSet.getColorOrWhite("MediumSpringGreen");
ug.apply(turtleColor1).apply(turtleColor2.bg()).apply(new UTranslate(x, -y)).draw(poly);
// ug.setAntiAliasing(true);
}
public void showTurtle() {
showTurtle = true;
}
public void hideTurtle() {
showTurtle = false;
}
public void setPenColor(HColor newPenColor) {
penColor = newPenColor;
}
void addLine(double x1, double y1, double x2, double y2) {
lines.add(new Rectangle2D.Double(x1, y1, x2, y2));
colors.add(penColor);
}
public void forward(double distance) {
double angle = dtor(turtleDirection);
double newX = x + distance * Math.cos(angle);
double newY = y + distance * Math.sin(angle);
if (penIsDown) {
addLine(x, y, newX, newY);
x = newX;
y = newY;
} else {
x = newX;
y = newY;
}
}
public void back(double distance) {
forward(-distance);
}
public void left(double turnAngle) {
turtleDirection += turnAngle;
while (turtleDirection > 360) {
turtleDirection -= 360;
}
while (turtleDirection < 0) {
turtleDirection += 360;
}
}
public void right(double turnAngle) {
left(-turnAngle);
}
public void penUp() {
penIsDown = false;
}
public void penDown() {
penIsDown = true;
}
public void paint(UGraphic ug) {
int n = lines.size();
for (int i = 0; i < n; i++) {
final HColor color = colors.get(i);
final Rectangle2D.Double r = lines.get(i);
final ULine line = new ULine(r.width - r.x, -r.height + r.y);
ug.apply(color).apply(new UTranslate(r.x, -r.y)).draw(line);
}
drawTurtle(ug);
if (message != null) {
final FontConfiguration font = FontConfiguration.blackBlueTrue(UFont.build("", Font.PLAIN, 14));
final TextBlock text = Display.create(message).create(font, HorizontalAlignment.LEFT,
new SpriteContainerEmpty());
final XDimension2D dim = text.calculateDimension(ug.getStringBounder());
final double textHeight = dim.getHeight();
text.drawU(ug.apply(UTranslate.dy((height - textHeight))));
}
}
public void message(String messageText) {
this.message = messageText;
}
}