/******************************************************************************* * Copyright (c) 2012 OpenLegacy Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * OpenLegacy Inc. - initial API and implementation *******************************************************************************/ package org.openlegacy.terminal.render; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openlegacy.exceptions.OpenLegacyRuntimeException; import org.openlegacy.terminal.TerminalField; import org.openlegacy.terminal.TerminalPosition; import org.openlegacy.terminal.TerminalRow; import org.openlegacy.terminal.TerminalSnapshot; import org.openlegacy.terminal.support.SimpleTerminalPosition; import org.openlegacy.terminal.support.SnapshotUtils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.List; import javax.imageio.ImageIO; public class DefaultTerminalSnapshotImageRenderer implements TerminalSnapshotImageRenderer { private final static Log logger = LogFactory.getLog(DefaultTerminalSnapshotImageRenderer.class); // default values for bean properties private Color imageBackgroundColor = Color.BLACK; private Color imageBoldFieldColor = Color.WHITE; private Color imageDefaultTextColor = Color.GREEN; private Color imageSorroundingTextColor = Color.WHITE; private int leftColumnsOffset = 2; private int topPixelsOffset = 2; private int imageWidth = 825; private int imageHeight = 400; private int fontSize = 15; private String fontFamily = "Monospaced"; private boolean drawLineNumbers = true; private int widthProportion = 10; private int heightProportion = 16; private int fontType = Font.BOLD; private boolean drawFieldSeparators = true; private boolean hidePasswordFields = true; public void render(TerminalSnapshot terminalSnapshot, OutputStream output) { BufferedImage buffer = new BufferedImage(885, 450, BufferedImage.TYPE_INT_RGB); if (logger.isDebugEnabled()) { logger.debug("Font set to:" + fontFamily); } Font font = new Font(fontFamily, fontType, fontSize); Graphics graphics = buffer.createGraphics(); graphics.setFont(font); setDefaultColor(graphics); markBackgroundAndInputFields(terminalSnapshot, graphics); drawText(terminalSnapshot, graphics); try { ImageIO.write(buffer, "jpg", output); } catch (IOException e) { throw (new OpenLegacyRuntimeException(e)); } } private void drawText(TerminalSnapshot terminalSnapshot, Graphics graphics) { int columns = terminalSnapshot.getSize().getColumns(); List<TerminalRow> rows = terminalSnapshot.getRows(); String screenText = terminalSnapshot.getText(); for (TerminalRow terminalRow : rows) { int rowNumber = terminalRow.getRowNumber(); int startY = toHeight(rowNumber); if (drawLineNumbers) { // draw row number graphics.setColor(imageSorroundingTextColor); graphics.drawString(String.valueOf(String.format("%2d", terminalRow.getRowNumber())), 0, startY); } int rowStart = (rowNumber - 1) * columns; // row is 1 based, drawing is 0 base String text = screenText.substring(rowStart, rowStart + columns); if (StringUtils.isBlank(text)) { continue; } for (int i = 0; i < text.length(); i++) { // text is 0 based, columns are 1 based TerminalField currentField = terminalSnapshot.getField(SimpleTerminalPosition.newInstance(rowNumber, i + 1)); if (currentField != null && currentField.getBackColor() != org.openlegacy.terminal.Color.BLACK) { graphics.setColor(imageBackgroundColor); } else { if (currentField != null) { graphics.setColor(SnapshotUtils.convertColor(currentField.getColor())); if (currentField.isBold() && currentField.getColor() == org.openlegacy.terminal.Color.GREEN) { graphics.setColor(imageBoldFieldColor); } } else { setDefaultColor(graphics); } } // 2 - place holder for row numbers char ch = text.charAt(i); if (hidePasswordFields && currentField != null && currentField.isPassword()) { if (currentField.isEmpty()) { ch = ' '; } else { ch = '*'; } } graphics.drawString(String.valueOf(ch), toWidth(i + leftColumnsOffset), startY); } } } private void markBackgroundAndInputFields(TerminalSnapshot terminalSnapshot, Graphics graphics) { int endX; List<TerminalField> fields = terminalSnapshot.getFields(); setDefaultColor(graphics); for (TerminalField terminalField : fields) { TerminalPosition position = terminalField.getPosition(); // -1 - pixels is 0 based , column is 1 based int startX = toWidth(position.getColumn() - 1 + leftColumnsOffset); int startY = toHeight(position.getRow()); endX = toWidth(terminalField.getEndPosition().getColumn() + leftColumnsOffset); if (terminalField.isEditable()) { graphics.drawLine(startX, startY, endX, startY); } int rowHeight = toHeight(1); if (terminalField.getBackColor() != org.openlegacy.terminal.Color.BLACK) { graphics.setColor(SnapshotUtils.convertColor(terminalField.getBackColor())); // graphics.fillRect(startX, toHeight(position.getRow() - 1) + topPixelsOffset, toWidth(terminalField.getLength()), rowHeight); } } if (drawFieldSeparators) { List<TerminalPosition> fieldSeperators = terminalSnapshot.getFieldSeperators(); graphics.setColor(imageDefaultTextColor); for (TerminalPosition terminalPosition : fieldSeperators) { graphics.drawString("^", toWidth(terminalPosition.getColumn() - 1 + leftColumnsOffset), toHeight(terminalPosition.getRow())); } } } private void setDefaultColor(Graphics graphics) { graphics.setColor(imageDefaultTextColor); } public int toHeight(int row) { return row * heightProportion; } public int toWidth(int column) { return column * widthProportion; } public String getFileFormat() { return "jpg"; } public void setImageHeight(int imageHeight) { this.imageHeight = imageHeight; } public void setImageWidth(int imageWidth) { this.imageWidth = imageWidth; } public void setFontFamily(String fontFamily) { this.fontFamily = fontFamily; } public void setDrawLineNumbers(boolean drawLineNumbers) { this.drawLineNumbers = drawLineNumbers; } public void setFontSize(int fontSize) { this.fontSize = fontSize; } public void setHeightProportion(int heightProportion) { this.heightProportion = heightProportion; } public void setWidthProportion(int widthProportion) { this.widthProportion = widthProportion; } public void setLeftColumnsOffset(int leftColumnsOffset) { this.leftColumnsOffset = leftColumnsOffset; } public void setTopPixelsOffset(int topPixelsOffset) { this.topPixelsOffset = topPixelsOffset; } public void setImageBackgroundColor(Color imageBackgroundColor) { this.imageBackgroundColor = imageBackgroundColor; } public void setImageBoldFieldColor(Color imageBoldFieldColor) { this.imageBoldFieldColor = imageBoldFieldColor; } public void setImageDefaultTextColor(Color imageDefaultTextColor) { this.imageDefaultTextColor = imageDefaultTextColor; } public void setImageSorroundingTextColor(Color imageSorroundingTextColor) { this.imageSorroundingTextColor = imageSorroundingTextColor; } public void setFontType(int fontType) { this.fontType = fontType; } public void setDrawFieldSeparators(boolean drawFieldSeparators) { this.drawFieldSeparators = drawFieldSeparators; } public void setHidePasswordFields(boolean hidePasswordFields) { this.hidePasswordFields = hidePasswordFields; } public int getLeftColumnsOffset() { return leftColumnsOffset; } public int getTopPixelsOffset() { return topPixelsOffset; } public int getMaxImageColumn() { return this.imageWidth / this.widthProportion; } public int getMaxImageRow() { return this.imageHeight / this.heightProportion; } }