mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2025-01-11 19:29:47 +00:00
Shape table fonts
This commit is contained in:
parent
ba59a64487
commit
a6ae3a0397
@ -1,5 +1,9 @@
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -19,184 +23,88 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
|
||||
public class ShapeTable extends AbstractFile
|
||||
{
|
||||
private final List<Shape> shapes = new ArrayList<Shape> ();
|
||||
private static final int SIZE = 400;
|
||||
private final int totalShapes;
|
||||
private final int[] shapeLength;
|
||||
private final int[] offsets;
|
||||
private int minSize = 9999;
|
||||
private int maxSize = 0;
|
||||
int maxWidth = 0;
|
||||
int maxHeight = 0;
|
||||
|
||||
public ShapeTable (String name, byte[] buffer)
|
||||
{
|
||||
super (name, buffer);
|
||||
|
||||
totalShapes = buffer[0] & 0xFF;
|
||||
shapeLength = new int[totalShapes];
|
||||
offsets = new int[totalShapes];
|
||||
int lastPtr = buffer.length;
|
||||
int minRow = 200;
|
||||
int minCol = 200;
|
||||
int maxRow = 200;
|
||||
int maxCol = 200;
|
||||
|
||||
for (int i = totalShapes - 1; i >= 0; i--)
|
||||
int totalShapes = buffer[0] & 0xFF;
|
||||
for (int i = 0; i < totalShapes; i++)
|
||||
{
|
||||
int ptr = HexFormatter.getShort (buffer, i * 2 + 2);
|
||||
int length = lastPtr - ptr;
|
||||
lastPtr = ptr;
|
||||
shapeLength[i] = length;
|
||||
offsets[i] = ptr;
|
||||
minSize = Math.min (minSize, length);
|
||||
maxSize = Math.max (maxSize, length);
|
||||
Shape shape = new Shape (buffer, i);
|
||||
shapes.add (shape);
|
||||
|
||||
minRow = Math.min (minRow, shape.minRow);
|
||||
minCol = Math.min (minCol, shape.minCol);
|
||||
maxRow = Math.max (maxRow, shape.maxRow);
|
||||
maxCol = Math.max (maxCol, shape.maxCol);
|
||||
}
|
||||
|
||||
maxHeight = maxRow - minRow + 1;
|
||||
maxWidth = maxCol - minCol + 1;
|
||||
for (Shape shape : shapes)
|
||||
shape.convertGrid (minRow, minCol, maxHeight, maxWidth);
|
||||
|
||||
int cols = (int) Math.sqrt (shapes.size ());
|
||||
int rows = (shapes.size () - 1) / cols + 1;
|
||||
|
||||
image = new BufferedImage ((cols + 1) * (maxWidth + 5), (rows + 1) * (maxHeight + 5),
|
||||
BufferedImage.TYPE_BYTE_GRAY);
|
||||
|
||||
int x = 10;
|
||||
int y = 10;
|
||||
int count = 0;
|
||||
Graphics2D g2d = image.createGraphics ();
|
||||
|
||||
for (Shape shape : shapes)
|
||||
{
|
||||
// System.out.println (shape);
|
||||
g2d.setComposite (
|
||||
AlphaComposite.getInstance (AlphaComposite.SRC_OVER, (float) 1.0));
|
||||
g2d.drawImage (shape.image, x, y, null);
|
||||
x += maxWidth + 5;
|
||||
if (++count % cols == 0)
|
||||
{
|
||||
x = 10;
|
||||
y += maxHeight + 5;
|
||||
}
|
||||
}
|
||||
g2d.dispose ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText ()
|
||||
{
|
||||
StringBuffer text = new StringBuffer ();
|
||||
StringBuilder text = new StringBuilder ();
|
||||
|
||||
int startPos = SIZE / 2;
|
||||
int maxWidth = 0;
|
||||
int maxHeight = 0;
|
||||
text.append (String.format ("File Name : %s%n", name));
|
||||
text.append (String.format ("File size : %,d%n", buffer.length));
|
||||
text.append (String.format ("Total shapes : %d%n", shapes.size ()));
|
||||
// text.append (String.format ("Smallest : %d%n", minSize));
|
||||
// text.append (String.format ("Largest : %d%n", maxSize));
|
||||
text.append (String.format ("Max dimensions : %d x %d%n%n", maxWidth, maxHeight));
|
||||
|
||||
for (int i = 0; i < totalShapes; i++)
|
||||
for (Shape shape : shapes)
|
||||
{
|
||||
int[][] grid = new int[SIZE][SIZE];
|
||||
int row = startPos;
|
||||
int col = startPos; // start in the middle of the grid
|
||||
if (i > 0)
|
||||
text.append ("\n");
|
||||
|
||||
text.append (String.format ("Shape : %d%n", i));
|
||||
text.append (String.format ("Size : %d%n", shapeLength[i]));
|
||||
|
||||
String bytes = HexFormatter.getHexString (buffer, offsets[i], shapeLength[i]);
|
||||
int ptr = offsets[i];
|
||||
for (String s : split (bytes))
|
||||
{
|
||||
text.append (String.format ("%04X : %s%n", ptr, s));
|
||||
ptr += 16;
|
||||
}
|
||||
|
||||
ptr = offsets[i];
|
||||
while (buffer[ptr] != 0)
|
||||
{
|
||||
int value = buffer[ptr++] & 0xFF;
|
||||
int v1 = value >> 6;
|
||||
int v2 = (value & 0x38) >> 3;
|
||||
int v3 = value & 0x07;
|
||||
|
||||
if (v3 >= 4)
|
||||
{
|
||||
grid[row][col] = 1;
|
||||
grid[0][col]++;
|
||||
grid[row][0]++;
|
||||
}
|
||||
if (v3 == 0 || v3 == 4)
|
||||
row--;
|
||||
else if (v3 == 1 || v3 == 5)
|
||||
col++;
|
||||
else if (v3 == 2 || v3 == 6)
|
||||
row++;
|
||||
else
|
||||
col--;
|
||||
|
||||
if (v2 >= 4)
|
||||
{
|
||||
grid[row][col] = 1;
|
||||
grid[0][col]++;
|
||||
grid[row][0]++;
|
||||
}
|
||||
if (v2 == 0 && v1 != 0)
|
||||
row--;
|
||||
else if (v2 == 4)
|
||||
row--;
|
||||
else if (v2 == 1 || v2 == 5)
|
||||
col++;
|
||||
else if (v2 == 2 || v2 == 6)
|
||||
row++;
|
||||
else if (v2 == 3 || v2 == 7)
|
||||
col--;
|
||||
|
||||
if (v1 == 1)
|
||||
col++;
|
||||
else if (v1 == 2)
|
||||
row++;
|
||||
else if (v1 == 3)
|
||||
col--;
|
||||
|
||||
}
|
||||
shape.drawText (text);
|
||||
text.append ("\n");
|
||||
|
||||
int minRow = startPos, maxRow = startPos;
|
||||
int minCol = startPos, maxCol = startPos;
|
||||
for (row = 1; row < grid.length; row++)
|
||||
{
|
||||
if (grid[row][0] > 0)
|
||||
{
|
||||
if (row < minRow)
|
||||
minRow = row;
|
||||
if (row > maxRow)
|
||||
maxRow = row;
|
||||
}
|
||||
}
|
||||
|
||||
for (col = 1; col < grid[0].length; col++)
|
||||
{
|
||||
if (grid[0][col] > 0)
|
||||
{
|
||||
if (col < minCol)
|
||||
minCol = col;
|
||||
if (col > maxCol)
|
||||
maxCol = col;
|
||||
}
|
||||
}
|
||||
|
||||
int width = maxCol - minCol + 1;
|
||||
int height = maxRow - minRow + 1;
|
||||
maxWidth = Math.max (maxWidth, width);
|
||||
maxHeight = Math.max (maxHeight, height);
|
||||
|
||||
for (row = minRow; row <= maxRow; row++)
|
||||
{
|
||||
for (col = minCol; col <= maxCol; col++)
|
||||
{
|
||||
if (col == startPos && row == startPos)
|
||||
text.append (grid[row][col] > 0 ? " @" : " .");
|
||||
else if (grid[row][col] == 0)
|
||||
text.append (" ");
|
||||
else
|
||||
text.append (" X");
|
||||
}
|
||||
text.append ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
text.deleteCharAt (text.length () - 1);
|
||||
|
||||
StringBuilder header = new StringBuilder ();
|
||||
header.append (String.format ("File Name : %s%n", name));
|
||||
header.append (String.format ("File size : %,d%n", buffer.length));
|
||||
header.append (String.format ("Total shapes : %d%n", totalShapes));
|
||||
header.append (String.format ("Smallest : %d%n", minSize));
|
||||
header.append (String.format ("Largest : %d%n", maxSize));
|
||||
header.append (String.format ("Max dimensions : %d x %d%n%n", maxWidth, maxHeight));
|
||||
|
||||
return header.toString () + text.toString ();
|
||||
}
|
||||
|
||||
private List<String> split (String line)
|
||||
{
|
||||
List<String> list = new ArrayList<String> ();
|
||||
while (line.length () > 48)
|
||||
{
|
||||
list.add (line.substring (0, 47));
|
||||
line = line.substring (48);
|
||||
}
|
||||
list.add (line);
|
||||
return list;
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
public static boolean isShapeTable (byte[] buffer)
|
||||
{
|
||||
if (buffer.length == 0 || buffer[buffer.length - 1] != 0)
|
||||
if (buffer.length == 0)
|
||||
return false;
|
||||
|
||||
int totalShapes = buffer[0] & 0xFF;
|
||||
@ -223,4 +131,211 @@ public class ShapeTable extends AbstractFile
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class Shape
|
||||
{
|
||||
private final byte[] buffer;
|
||||
private final int index;
|
||||
|
||||
int offset;
|
||||
int actualLength;
|
||||
int minRow, maxRow;
|
||||
int minCol, maxCol;
|
||||
// int endRow, endCol;
|
||||
int startRow = SIZE / 2;
|
||||
int startCol = SIZE / 2;
|
||||
int[][] grid = new int[SIZE][SIZE];
|
||||
int[][] displayGrid;
|
||||
// int height, width;
|
||||
|
||||
private BufferedImage image;
|
||||
|
||||
public Shape (byte[] buffer, int index)
|
||||
{
|
||||
this.index = index;
|
||||
this.buffer = buffer;
|
||||
|
||||
int row = startRow;
|
||||
int col = startCol;
|
||||
|
||||
offset = HexFormatter.getShort (buffer, index * 2 + 2);
|
||||
|
||||
int ptr = offset;
|
||||
while (ptr < buffer.length)
|
||||
{
|
||||
int value = buffer[ptr++] & 0xFF;
|
||||
|
||||
if (value == 0)
|
||||
break;
|
||||
|
||||
// P = plot
|
||||
// DD = direction to move
|
||||
int v1 = value >>> 6; // DD......
|
||||
int v2 = (value & 0x38) >>> 3; // ..PDD...
|
||||
int v3 = value & 0x07; // .....PDD
|
||||
|
||||
// rightmost 3 bits
|
||||
if (v3 >= 4)
|
||||
plot (grid, row, col);
|
||||
|
||||
if (v3 == 0 || v3 == 4)
|
||||
row--;
|
||||
else if (v3 == 1 || v3 == 5)
|
||||
col++;
|
||||
else if (v3 == 2 || v3 == 6)
|
||||
row++;
|
||||
else
|
||||
col--;
|
||||
|
||||
// middle 3 bits
|
||||
if (v2 >= 4)
|
||||
plot (grid, row, col);
|
||||
|
||||
// cannot move up without plotting if v1 is zero
|
||||
if ((v2 == 0 && v1 != 0) || v2 == 4)
|
||||
row--;
|
||||
else if (v2 == 1 || v2 == 5)
|
||||
col++;
|
||||
else if (v2 == 2 || v2 == 6)
|
||||
row++;
|
||||
else if (v2 == 3 || v2 == 7)
|
||||
col--;
|
||||
|
||||
// leftmost 2 bits (cannot plot or move up)
|
||||
if (v1 == 1)
|
||||
col++;
|
||||
else if (v1 == 2)
|
||||
row++;
|
||||
else if (v1 == 3)
|
||||
col--;
|
||||
}
|
||||
|
||||
actualLength = ptr - offset;
|
||||
|
||||
// endRow = row;
|
||||
// endCol = col;
|
||||
|
||||
// find min and max rows with pixels
|
||||
minRow = startRow;
|
||||
maxRow = startRow;
|
||||
// minRow = Math.min (minRow, endRow);
|
||||
// maxRow = Math.max (maxRow, endRow);
|
||||
for (row = 1; row < grid.length; row++)
|
||||
{
|
||||
if (grid[row][0] > 0)
|
||||
{
|
||||
minRow = Math.min (minRow, row);
|
||||
maxRow = Math.max (maxRow, row);
|
||||
}
|
||||
}
|
||||
|
||||
// find min and max columns with pixels
|
||||
minCol = startCol;
|
||||
maxCol = startCol;
|
||||
// minCol = Math.min (minCol, endCol);
|
||||
// maxCol = Math.max (maxCol, endCol);
|
||||
for (col = 1; col < grid[0].length; col++)
|
||||
{
|
||||
if (grid[0][col] > 0)
|
||||
{
|
||||
minCol = Math.min (minCol, col);
|
||||
maxCol = Math.max (maxCol, col);
|
||||
}
|
||||
}
|
||||
|
||||
// height = maxRow - minRow + 1;
|
||||
// width = maxCol - minCol + 1;
|
||||
// System.out.printf ("%4d %4d %4d %4d %4d%n",
|
||||
// index, minRow, maxRow, minCol,
|
||||
// maxCol);
|
||||
}
|
||||
|
||||
void convertGrid (int offsetRows, int offsetColumns, int rows, int columns)
|
||||
{
|
||||
// System.out.printf ("Converting shape # %d%n", index);
|
||||
// System.out.printf ("offsetRows %d offsetCols %d%n", offsetRows,
|
||||
// offsetColumns);
|
||||
// System.out.printf ("rows %d cols %d%n", rows, columns);
|
||||
|
||||
displayGrid = new int[rows][columns];
|
||||
for (int row = 0; row < rows; row++)
|
||||
for (int col = 0; col < columns; col++)
|
||||
displayGrid[row][col] = grid[offsetRows + row][offsetColumns + col];
|
||||
grid = null;
|
||||
|
||||
// draw the image
|
||||
image = new BufferedImage (columns, rows, BufferedImage.TYPE_BYTE_GRAY);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
for (int row = 0; row < rows; row++)
|
||||
for (int col = 0; col < columns; col++)
|
||||
dataBuffer.setElem (element++, displayGrid[row][col] == 0 ? 0 : 255);
|
||||
|
||||
startRow -= offsetRows;
|
||||
startCol -= offsetColumns;
|
||||
// endRow -= offsetRows;
|
||||
// endCol -= offsetColumns;
|
||||
}
|
||||
|
||||
private void plot (int[][] grid, int row, int col)
|
||||
{
|
||||
grid[row][col] = 1; // plot
|
||||
grid[0][col]++; // increment total column dots
|
||||
grid[row][0]++; // increment total row dots
|
||||
}
|
||||
|
||||
public void drawText (StringBuilder text)
|
||||
{
|
||||
text.append (String.format ("Shape : %d%n", index));
|
||||
text.append (String.format ("Size : %d%n", actualLength));
|
||||
// text.append (String.format ("Width : %d%n", width));
|
||||
// text.append (String.format ("Height : %d%n", height));
|
||||
|
||||
// append the shape's data
|
||||
String bytes = HexFormatter.getHexString (buffer, offset, actualLength);
|
||||
int ptr = offset;
|
||||
for (String s : split (bytes))
|
||||
{
|
||||
text.append (String.format (" %04X : %s%n", ptr, s));
|
||||
ptr += 16;
|
||||
}
|
||||
text.append ("\n");
|
||||
|
||||
for (int row = 0; row < displayGrid.length; row++)
|
||||
{
|
||||
for (int col = 0; col < displayGrid[0].length; col++)
|
||||
if (col == startCol && row == startRow)
|
||||
text.append (displayGrid[row][col] > 0 ? " @" : " .");
|
||||
// else if (col == endCol && row == endRow)
|
||||
// text.append (displayGrid[row][col] > 0 ? " #" : " .");
|
||||
else if (displayGrid[row][col] == 0)
|
||||
text.append (" ");
|
||||
else
|
||||
text.append (" X");
|
||||
|
||||
text.append ("\n");
|
||||
}
|
||||
|
||||
text.append ("\n");
|
||||
}
|
||||
|
||||
private List<String> split (String line)
|
||||
{
|
||||
List<String> list = new ArrayList<String> ();
|
||||
while (line.length () > 48)
|
||||
{
|
||||
list.add (line.substring (0, 47));
|
||||
line = line.substring (48);
|
||||
}
|
||||
list.add (line);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return String.format ("%3d %3d %3d %3d %3d", index, minRow, maxRow, minCol,
|
||||
maxCol);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user