Make renderer better and support text

This commit is contained in:
Minecon724 2024-10-04 18:33:09 +02:00
parent d3c1f9c56b
commit ce738abbc8
Signed by: Minecon724
GPG key ID: 3CCC4D267742C8E8

View file

@ -3,27 +3,75 @@ package eu.m724;
import org.jfree.svg.SVGGraphics2D;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
public class Renderer {
private static final int TILE_SIZE = 50;
public static String render(Crossword crossword) {
SVGGraphics2D g2 = new SVGGraphics2D(crossword.width() * 10, crossword.height() * 10);
SVGGraphics2D g2 = new SVGGraphics2D(crossword.width() * TILE_SIZE, crossword.height() * TILE_SIZE);
g2.setPaint(Color.BLACK);
FontRenderContext frc = g2.getFontRenderContext();
Font font = g2.getFont();
for (PlacedWord word : crossword.words()) {
int x = word.x();
int y = word.y();
String hint = word.word().hint();
if (word.vertical()) {
for (int _y=y; _y<y+word.wordLength(); _y++) {
g2.draw(new Rectangle(x * 10, _y * 10, 10, 10));
drawStringFit(g2, x * TILE_SIZE, (y - 1) * TILE_SIZE, hint);
//g2.drawString(word.word().hint(), x * TILE_SIZE, (y) * TILE_SIZE);
for (int i=0; i<word.length(); i++) {
g2.draw(new Rectangle(x * TILE_SIZE, (y + i) * TILE_SIZE, TILE_SIZE, TILE_SIZE));
}
} else {
for (int _x=x; _x<x+word.wordLength(); _x++) {
g2.draw(new Rectangle(_x * 10, y * 10, 10, 10));
drawStringFit(g2, (x - 1) * TILE_SIZE, y * TILE_SIZE, hint);
//g2.drawString(word.word().hint(), (x) * 10, y * 10);
for (int i=0; i<word.length(); i++) {
g2.draw(new Rectangle((x + i) * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE));
}
}
}
//g2.draw(new Rectangle(10, 10, 280, 180));
return g2.getSVGDocument();
}
// TODO beautify
private static void drawStringFit(SVGGraphics2D graphics2D, int x, int y, String text) {
FontRenderContext frc = graphics2D.getFontRenderContext();
Font font = graphics2D.getFont();
Rectangle2D bounds = font.getStringBounds(text, frc);
int textWidth = (int) bounds.getWidth();
int textHeight = (int) bounds.getHeight();
String[] lines;
if (textWidth > TILE_SIZE) { // TODO ideally this should be splitting by word
int linesAmount = (int) Math.ceil((double) textWidth / TILE_SIZE);
lines = new String[linesAmount];
int partLength = text.length() / linesAmount;
for (int i=0; i<linesAmount; i++) {
lines[i] = text.substring(partLength * i, partLength * (i + 1));
}
// in case the ending was lost due to imprecise division
if (partLength * linesAmount < text.length()) {
lines[linesAmount - 1] += text.substring(partLength * linesAmount);
}
} else {
lines = new String[] { text };
}
for (int i=0; i<lines.length; i++) {
String line = lines[i];
bounds = font.getStringBounds(line, frc);
graphics2D.drawString(line, x, y + (textHeight * i));
}
}
}