/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.rp181.datarender; import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.image.BufferedImage; import org.rp181.dataview.CurrentDataTopComponent; import org.rp181.dataview.SettingsTopComponent; import org.rp181.logicdata.Logic8Set; /** * * @author phani */ public class Renderer { private static Renderer instance = null; ColorSet defaultColorSet = new ColorSet(); // public static final int LEFT_SIDE_MARGIN = 100; private static final int TOP_MARGIN = 40; private double zoom = 1; /** * */ private int xoff = 0; private int width = -1; private int height = -1; private int[] chanMap = new int[8]; FontMetrics fm; boolean color = true; public boolean leftMargin = true; boolean topMargin = true; boolean coloredLines = true; public int currentChannel = 1; public int currentRow = 1; BufferedImage image; Graphics g = null; int sampleStep; int rowHeight; int data[]; double time; Logic8Set currentSet; SettingsTopComponent settings; // BufferedImage background; Graphics backgroundGraphics; BufferedImage channels; Graphics channelsGraphics; BufferedImage highlight; Graphics highlightGraphics; BufferedImage datadisplay; Graphics dataGraphics; BufferedImage cursors; Graphics cursorsGraphics; int oldRowsActivated = -1; boolean updateBackground = true; boolean updateChannels = true; boolean updateData = true; public Renderer getInstance() { if (instance == null) { instance = new Renderer(); } return instance; } public void setZoom(double z) { zoom = z; updateData = true; } public double getZoom() { return zoom; } public void setOffset(int x) { xoff = x; updateData = true; } public int getOffset() { return xoff; } Color darkBg = new Color(20, 20, 20); int left; int top; int xP; int yP; public BufferedImage render(int w, int h, int xP, int yP, Logic8Set dat) { this.xP = xP; this.yP = yP; currentSet = dat; settings = SettingsTopComponent.getDefault(); if (settings.colorB.isSelected()) { defaultColorSet.setColorMode(ColorSet.MODE_COLOR); } else { defaultColorSet.setColorMode(ColorSet.MODE_BLACK_AND_WHITE); } //if (upToDate == false) { try { color = settings.colorB.isSelected(); leftMargin = settings.leftM.isSelected(); topMargin = settings.topM.isSelected(); coloredLines = settings.colorLines.isSelected(); if (!leftMargin) { left = 0; } else { left = LEFT_SIDE_MARGIN; } if (!topMargin) { top = 0; } else { top = TOP_MARGIN; } if (w != width || h != height) { width = w; height = h; background = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); backgroundGraphics = background.createGraphics(); cursors = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); cursorsGraphics = background.createGraphics(); channels = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); channelsGraphics = background.createGraphics(); datadisplay = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); dataGraphics = background.createGraphics(); highlight = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); highlightGraphics = background.createGraphics(); updateBackground = true; updateData = true; } image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); g = image.createGraphics(); fm = g.getFontMetrics(); sampleStep = (int) ((currentSet.getSampleLength() / (long) width) - left); sampleStep = (int) ((double) sampleStep / zoom); rowHeight = (height - top) / rowsActivated(); while ((xoff + width) * sampleStep > currentSet.getSampleLength()) { xoff--; } xoff = Math.max(0, xoff); currentRow = -1; for (int d = 1; d <= 8; d++) { if (isActivated(d)) { currentRow++; chanMap[d - 1] = currentRow; } else { chanMap[d - 1] = -1; } } if (updateBackground) { drawBackground(); } if (oldRowsActivated != rowsActivated()) { drawChannels(); } if (settings.chanHigh.isSelected() && color && yP > 0) { drawHighlight(); } if (updateData) { drawData(); } updateCursors(); g.drawImage(background, 0, 0, null); g.drawImage(channels, 0, 0, null); if (settings.chanHigh.isSelected() && color && yP > 0) { g.drawImage(highlight, 0, 0, null); } g.drawImage(datadisplay, 0, 0, null); g.drawImage(cursors, 0, 0, null); return image; } catch (Exception e) { e.printStackTrace(); g.drawImage(background, 0, 0, null); g.drawImage(channels, 0, 0, null); return image; } } //return null; } public void drawInfo(Graphics g, int x, int y, int rowHeight, long sampleStep) { int rowY = y; if (topMargin) { rowY -= TOP_MARGIN; } int row = 0; while (rowY > rowHeight) { rowY -= rowHeight; row++; } int d = -1; for (int i = 0; i < 8; i++) { if (chanMap[i] == row) { d = i + 1; } } int xPos = x; if (leftMargin) { xPos -= LEFT_SIDE_MARGIN; } //xPos = xoff; CurrentDataTopComponent.getDefault().channel.setText("Channel " + (row + 1)); Long[] cData = currentSet.getCompressedData(row); CurrentDataTopComponent.getDefault().stateChanges.setText("State Changes: " + cData.length + ""); CurrentDataTopComponent.getDefault().totalTime.setText("Total Time: " + currentSet.getSampleLength() * currentSet.getTimeStep() + ""); CurrentDataTopComponent.getDefault().startSample.setText("Start Sample #: "); CurrentDataTopComponent.getDefault().stopSample.setText("Stop Sample #: "); CurrentDataTopComponent.getDefault().time.setText("Segment Time: "); long cursor = getSampleNumber(xPos); long sampleNum = 0; long oldSampleNum = 0; for (int i = 0; i < cData.length; i++) { oldSampleNum = sampleNum; sampleNum += cData[i]; if (cursor <= sampleNum) { g.setColor(defaultColorSet.getInfoLineColor()); CurrentDataTopComponent.getDefault().startSample.setText("Start Sample #: " + oldSampleNum); CurrentDataTopComponent.getDefault().stopSample.setText("Stop Sample #: " + sampleNum); CurrentDataTopComponent.getDefault().time.setText("Segment Time: " + ((sampleNum - oldSampleNum) * currentSet.getTimeStep()) + " S"); if (!leftMargin) { g.drawLine((int) (oldSampleNum / sampleStep) - xoff, y, (int) (sampleNum / sampleStep) - xoff, y); } else { g.drawLine(Math.max(LEFT_SIDE_MARGIN, (int) (oldSampleNum / sampleStep) - xoff + LEFT_SIDE_MARGIN), y, (int) (sampleNum / sampleStep) - xoff + LEFT_SIDE_MARGIN, y); } break; } } } public boolean intToBoolean(int i) { if (i > 0) { return true; } else { return false; } } public int getCurrentChannel() { return currentChannel; } Color bgColor = new Color(80, 80, 80); private void highlight(int yP, int rowHeight, Graphics g, int left, int top, int sampleStep) { int rowY = yP; if (topMargin) { rowY -= TOP_MARGIN; } int row = 0; while (rowY > rowHeight) { rowY -= rowHeight; row++; } int d = -1; for (int i = 0; i < 8; i++) { if (chanMap[i] == row) { d = i + 1; } } if (color && d > 0) { drawPlate(bgColor, g, left, (rowHeight) * row + top, width - left, rowHeight - 10); g.setColor(Color.white); if (coloredLines) { g.setColor(defaultColorSet.getChannelColor(d)); if (d == 8) { g.setColor(Color.white); } } int prev = -1; for (int i = 0; i < width; i++) { data = currentSet.getSample((i + xoff) * sampleStep); if (prev < 0) { prev = data[d - 1]; } else { if (data[d - 1] != prev) { prev = data[d - 1]; g.drawLine(i - 1 + left, ((rowHeight / 5) + rowHeight * row) + top, i - 1 + left, ((rowHeight / 5) * 4 + rowHeight * row) + top); } } boolean thick = false; int y = ((rowHeight) / 5) * data[d - 1]; if (y == 0) { y = ((rowHeight) / 5) * 4; thick = true; } y += (rowHeight) * row; y += top; if (!thick) { g.fillRect(i + left, y, 1, 1); } else { if (settings.thickBottom.isSelected()) { g.fillRect(i + left, y - 1, 1, 1); } g.fillRect(i + left, y, 1, 1); } } } } public long getSampleNumber(int x) { long sampleNum = -1; if (x > width || x < 0) { return sampleNum; } else { int left; if (!leftMargin) { left = 0; } else { left = LEFT_SIDE_MARGIN; } int sampleStepC = (int) ((currentSet.getSampleLength() / (long) width) - left); sampleStepC = (int) ((double) sampleStepC / zoom); return (x + xoff) * sampleStepC; } } Color co; /** * * @param c * @param g * @param x * @param y * @param width * @param height */ public void drawPlate(Color c, Graphics g, int x, int y, int width, int height) { for (int i = 0; i <= 10; i++) { co = new Color(Math.max(c.getRed() - (100 - i * 10), 0), Math.max(c.getGreen() - (100 - i * 10), 0), Math.max(c.getBlue() - (100 - i * 10), 0)); g.setColor(co); g.fillRect(x, y + i, width, height); } g.setColor(c); g.fillRect(x, y + 10, width, height - 10); } public void repaintNow() { updateBackground = true; updateData = true; } /** * * @param i * @return */ public boolean isActivated(int i) { return settings.chanField.getText().contains(i + ""); } /** * * @return */ public int rowsActivated() { String str = settings.chanField.getText(); int rows = 0; if (str.contains("1")) { rows++; } if (str.contains("2")) { rows++; } if (str.contains("3")) { rows++; } if (str.contains("4")) { rows++; } if (str.contains("5")) { rows++; } if (str.contains("6")) { rows++; } if (str.contains("7")) { rows++; } if (str.contains("8")) { rows++; } return rows; } private void drawBackground() { backgroundGraphics.setColor(defaultColorSet.getBackgroundColor()); backgroundGraphics.fillRect(0, 0, width, height); } private void drawChannels() { //channels = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); //channelsGraphics = channels.createGraphics(); channelsGraphics.setColor(clear); channelsGraphics.fillRect(0, 0, width, height); for (int d = 1; d <= 8; d++) { currentRow = chanMap[d - 1]; if (isActivated(d)) { if (color) { drawPlate(defaultColorSet.getBackgroundColor(), channelsGraphics, left, (rowHeight) * currentRow + top, width - left, rowHeight); } if (leftMargin) { if (color) { channelsGraphics.setColor(defaultColorSet.getChannelColor(d)); drawPlate(defaultColorSet.getChannelColor(d), channelsGraphics, 0, (rowHeight) * currentRow + top, 20, rowHeight); drawPlate(darkBg, channelsGraphics, 20, (rowHeight) * currentRow + top, left - 20, rowHeight); } if (settings.chanText.isSelected()) { channelsGraphics.setColor(defaultColorSet.getTextColor()); channelsGraphics.drawString("Channel " + d, 30, (rowHeight) * (currentRow) + top + 25); } } } } } private void drawHighlight() { // highlight = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); // highlightGraphics = highlight.createGraphics(); highlightGraphics.setColor(clear); highlightGraphics.fillRect(0, 0, width, height); highlight(yP, rowHeight, highlightGraphics, left, top, sampleStep); } private void drawData() { // datadisplay = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); //dataGraphics = datadisplay.createGraphics(); dataGraphics.setColor(clear); dataGraphics.fillRect(0, 0, width, height); for (int d = 1; d <= 8; d++) { if (isActivated(d)) { currentRow = chanMap[d - 1]; int prev = -1; for (int i = 0; i < width; i++) { if (i % 200 == 0 && settings.timingMarkers.isSelected()) { dataGraphics.setColor(defaultColorSet.getTextColor()); time = ((i + xoff) * sampleStep) * currentSet.getTimeStep(); String str = ""; String str2 = null; if (time >= 1 || time == 0) { str = time + ""; str = str.substring(0, 1); str = str + " S"; str2 = ((time - Integer.parseInt(str.replaceAll(" S", ""))) * 1000) + ""; str2 = str2.substring(0, Math.min(6, str2.length())); if (Double.parseDouble(str2) == 0) { str2 = null; } else { str2 = str2.concat(" ms"); } dataGraphics.drawString(str, i + left - (fm.stringWidth(str) / 2), top - 25); if (str2 != null) { dataGraphics.drawString(str2, i + left - (fm.stringWidth(str2) / 2), top - 12); } } else { str = (time * 1000) + ""; str = str.substring(0, Math.min(5, str.length())); str = str + " ms"; dataGraphics.drawString(str, i + left - (fm.stringWidth(str) / 2), top - 12); } dataGraphics.fillRect(i + left - 2, top - 5, 4, 4); } if (!color) { dataGraphics.setColor(Color.black); } else if (coloredLines) { dataGraphics.setColor(defaultColorSet.getChannelColor(d)); if (d == 8) { dataGraphics.setColor(Color.white); } } data = currentSet.getSample((i + xoff) * sampleStep); if (prev < 0) { prev = data[d - 1]; } else { if (data[d - 1] != prev) { prev = data[d - 1]; dataGraphics.drawLine(i - 1 + left, ((rowHeight / 5) + rowHeight * currentRow) + top, i - 1 + left, ((rowHeight / 5) * 4 + rowHeight * currentRow) + top); } } boolean thick = false; int y = ((rowHeight) / 5) * data[d - 1]; if (y == 0) { y = ((rowHeight) / 5) * 4; thick = true; } y += (rowHeight) * currentRow; y += top; if (!thick) { dataGraphics.fillRect(i + left, y, 1, 1); } else { if (settings.thickBottom.isSelected()) { dataGraphics.fillRect(i + left, y - 1, 1, 1); } dataGraphics.fillRect(i + left, y, 1, 1); } } } } } private void updateCursors() { // cursors = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); //cursorsGraphics = cursors.createGraphics(); cursorsGraphics.setColor(clear); cursorsGraphics.fillRect(0, 0, width, height); if (settings.vertCursor.isSelected()) { cursorsGraphics.setColor(defaultColorSet.getVerticalCursorColor()); if (leftMargin) { cursorsGraphics.drawLine(Math.max(0, xP), top, xP, height); } else { cursorsGraphics.drawLine(xP, top, xP, height); } } drawInfo(cursorsGraphics, xP, yP, rowHeight, sampleStep); } private Color clear = new Color(255, 255, 255, 0); }