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(); } }