org.openlegacy.terminal.render.DefaultTerminalSnapshotImageRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.openlegacy.terminal.render.DefaultTerminalSnapshotImageRenderer.java

Source

/*******************************************************************************
 * Copyright (c) 2014 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;

    @Override
    public void render(TerminalSnapshot terminalSnapshot, OutputStream output) {

        BufferedImage buffer;

        int width = 885;
        int height = 450;
        if (terminalSnapshot.getSize().getColumns() == 132) {
            width = 1460;
        }
        imageWidth = width;
        imageHeight = height;

        buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        if (logger.isTraceEnabled()) {
            logger.trace("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;
    }

    @Override
    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;
    }

    public double fromHeight(int row) {

        return (double) row / heightProportion;
    }

    public double fromWidth(int col) {
        return (double) col / widthProportion;
    }

}