package jetbrains.mps.lang.editor.imageGen.plugin;
/*Generated by MPS */
import org.jetbrains.mps.openapi.model.SNodeReference;
import org.jetbrains.mps.openapi.module.SRepository;
import java.io.ByteArrayOutputStream;
import org.jetbrains.annotations.Nullable;
import java.awt.Color;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.editor.runtime.HeadlessEditorComponent;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.image.RenderedImage;
import jetbrains.mps.nodeEditor.cells.EditorCell;
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Graphics;
import java.awt.Rectangle;
public class PrintNodeRunnable implements Runnable {
private boolean myExecuted;
private SNodeReference myNodeReference;
private SRepository myRepository;
private ByteArrayOutputStream myResult;
private String myErrorMessage = null;
private double myScaleFactor = 2;
@Nullable
private Color myBackgroundColor;
@NotNull
private String myImageFormat = "png";
@NotNull
private String myShortFileName;
public PrintNodeRunnable(SNodeReference nodeReference, SRepository repository, @NotNull String shortFileName) {
myNodeReference = nodeReference;
myRepository = repository;
myShortFileName = shortFileName;
}
public void setImageFormat(@NotNull String format) {
myImageFormat = format;
}
public void setScale(double scale) {
myScaleFactor = scale;
}
public void setBackgroundColor(int r, int g, int b, int a) {
myBackgroundColor = new Color(r, g, b, a);
}
public void run() {
try {
doPrintNode();
} finally {
synchronized (this) {
myExecuted = true;
notifyAll();
}
}
}
public boolean waitForExecution() {
try {
synchronized (this) {
while (!(myExecuted)) {
wait();
}
}
} catch (InterruptedException e) {
}
return myResult != null;
}
public String getErrorMessage() {
return myErrorMessage;
}
public byte[] getResult() {
return myResult.toByteArray();
}
public String getFileName() {
return myShortFileName + "." + myImageFormat;
}
private void doPrintNode() {
SNode node = myNodeReference.resolve(myRepository);
if (node == null) {
myErrorMessage = "Can't find node " + myNodeReference + " inside repository: " + myRepository;
return;
}
HeadlessEditorComponent editorComponent = new HeadlessEditorComponent(node, myRepository);
try {
try {
myResult = new ByteArrayOutputStream();
boolean successful = ImageIO.write(printCellToImage(editorComponent.getRootCell()), myImageFormat, myResult);
if (!(successful)) {
myResult = null;
myErrorMessage = "Image export was not successful. Check if specified format is supported: " + myImageFormat;
}
} catch (IOException ioex) {
myResult = null;
myErrorMessage = "Exception while writing image: " + ioex.toString();
}
} finally {
editorComponent.dispose();
}
}
private RenderedImage printCellToImage(EditorCell cell) {
BufferedImage image = new BufferedImage(scale(cell.getWidth()), scale(cell.getHeight()), BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.scale(myScaleFactor, myScaleFactor);
graphics.translate(-cell.getX(), -cell.getY());
graphics.setClip(cell.getX(), cell.getY(), cell.getWidth(), cell.getHeight());
paintBackground(graphics.create());
cell.paint(graphics);
graphics.dispose();
return image;
}
private int scale(int value) {
return (int) (value * myScaleFactor);
}
private void paintBackground(Graphics graphics) {
if (myBackgroundColor != null) {
Rectangle clipBounds = graphics.getClip().getBounds();
graphics.setColor(myBackgroundColor);
graphics.fillRect(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
}
graphics.dispose();
}
}