168 lines
5.7 KiB
Java
168 lines
5.7 KiB
Java
package haus.nightmare.lib3270j.graphics;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
public class ProgramSymbolManagerTest {
|
|
|
|
@Test
|
|
public void testSetAllocationAndLookup() {
|
|
ProgramSymbolManager manager = new ProgramSymbolManager();
|
|
// Loadable set can be queried after loadps or clearAll
|
|
assertNull(manager.getSymbolSet(0x40));
|
|
assertNull(manager.getSymbol(0x40, 0x41));
|
|
|
|
manager.clearAll();
|
|
assertNull(manager.getSymbolSet(0x40));
|
|
}
|
|
|
|
@Test
|
|
public void testSinglePlaneLoadPsFormat1() {
|
|
ProgramSymbolManager manager = new ProgramSymbolManager();
|
|
|
|
// Build Format 1 Load PS payload for LCID 0x40, code point 0x41 ('A')
|
|
// Format 1 header:
|
|
// byte 0: flags (0x01: format 1, single plane)
|
|
// byte 1: LCID (0x40)
|
|
// byte 2: Start code point (0x41)
|
|
// byte 3: RWS (0x02: loadable slot 2)
|
|
// followed by 18 bytes per symbol for 9x16 cell:
|
|
// Byte 0-1: Col 0 for rows 0..15 (0x80 = bit for row 0 col 0)
|
|
// Bytes 2-17: Cols 1..8 for rows 0..15 (0xFF = bits for row 0 cols 1..8)
|
|
byte[] payload = new byte[4 + 18];
|
|
payload[0] = 0x01; // Format 1
|
|
payload[1] = 0x40; // LCID 0x40
|
|
payload[2] = 0x41; // Code point 0x41
|
|
payload[3] = 0x02; // RWS 2
|
|
|
|
payload[4] = (byte) 0x80; // Row 0 Col 0 bit
|
|
payload[5] = (byte) 0x00; // Rows 8..15 Col 0
|
|
for (int r = 0; r < 16; r++) {
|
|
payload[6 + r] = (byte) 0xFF; // Cols 1..8 on all rows
|
|
}
|
|
|
|
manager.loadps(payload);
|
|
|
|
ProgramSymbolSet set = manager.getSymbolSet(0x40);
|
|
assertNotNull(set);
|
|
assertEquals(0x40, set.getLcid());
|
|
assertFalse(set.isTriplePlane());
|
|
|
|
ProgramSymbolSet.SymbolSlot slot = manager.getSymbol(0x40, 0x41);
|
|
assertNotNull(slot);
|
|
assertEquals(9, slot.getWidth());
|
|
assertEquals(12, slot.getHeight());
|
|
assertFalse(slot.isTriplePlane());
|
|
|
|
// Verify pixel data (Row 0 Col 0 is 1)
|
|
byte[] pixels = slot.getPixelData();
|
|
assertNotNull(pixels);
|
|
assertEquals(1, pixels[0]); // Row 0 Col 0 is 1
|
|
|
|
// Test rendering into 32-bit ARGB pixels
|
|
int fg = 0xFF00FF00; // Green
|
|
int bg = 0xFF000000; // Black
|
|
int[] rgb = slot.getRgbPixels(fg, bg);
|
|
assertNotNull(rgb);
|
|
assertEquals(9 * 12, rgb.length);
|
|
assertEquals(fg, rgb[0]); // Row 0 Col 0 pixel should be foreground Green
|
|
}
|
|
|
|
@Test
|
|
public void testExplicitCellDimensions() {
|
|
ProgramSymbolManager manager = new ProgramSymbolManager();
|
|
manager.setDefaultCellDimensions(9, 16);
|
|
|
|
byte[] payload = new byte[4 + 18];
|
|
payload[0] = 0x01; // Format 1
|
|
payload[1] = 0x40; // LCID 0x40
|
|
payload[2] = 0x41; // Code point 0x41
|
|
payload[3] = 0x02; // RWS 2
|
|
payload[4] = (byte) 0x80;
|
|
payload[5] = (byte) 0x00;
|
|
for (int r = 0; r < 16; r++) {
|
|
payload[6 + r] = (byte) 0xFF;
|
|
}
|
|
|
|
manager.loadps(payload);
|
|
ProgramSymbolSet.SymbolSlot slot = manager.getSymbol(0x40, 0x41);
|
|
assertNotNull(slot);
|
|
assertEquals(9, slot.getWidth());
|
|
assertEquals(16, slot.getHeight());
|
|
}
|
|
|
|
@Test
|
|
public void testTriplePlaneMultiColorComposite() {
|
|
ProgramSymbolManager manager = new ProgramSymbolManager();
|
|
|
|
// Build Format 1 Load PS payload for LCID 0x42, triple plane
|
|
// flags = 0x01 (Format 1)
|
|
// RWS = 4 (Triple Plane)
|
|
byte[] payload = new byte[4 + 18];
|
|
payload[0] = 0x01; // Format 1
|
|
payload[1] = 0x42; // LCID 0x42
|
|
payload[2] = 0x45; // Code point 0x45
|
|
payload[3] = 0x04; // RWS 4 (Triple Plane)
|
|
|
|
// Set pixel at row 0 col 0
|
|
payload[4] = (byte) 0x80; // Row 0 Col 0
|
|
payload[5] = (byte) 0x00;
|
|
for (int r = 0; r < 16; r++) {
|
|
payload[6 + r] = (byte) 0x00;
|
|
}
|
|
|
|
manager.loadps(payload);
|
|
|
|
ProgramSymbolSet set = manager.getSymbolSet(0x42);
|
|
assertNotNull(set);
|
|
assertTrue(set.isTriplePlane());
|
|
|
|
ProgramSymbolSet.SymbolSlot slot = manager.getSymbol(0x42, 0x45);
|
|
assertNotNull(slot);
|
|
assertTrue(slot.isTriplePlane());
|
|
|
|
// When loaded with colorPlane=0 (default), all 3 planes are set (val 7 = white composite)
|
|
byte[] pixels = slot.getPixelData();
|
|
assertEquals(7, pixels[0] & 0xFF);
|
|
|
|
// Render ARGB pixels
|
|
int[] rgb = slot.getRgbPixels(0xFFFFFFFF, 0xFF000000);
|
|
assertNotNull(rgb);
|
|
|
|
// Pixel (0,0) should be white composite (0xFFFFFFFF)
|
|
int pixelArgb = rgb[0];
|
|
int r = (pixelArgb >> 16) & 0xFF;
|
|
int g = (pixelArgb >> 8) & 0xFF;
|
|
int b = pixelArgb & 0xFF;
|
|
assertEquals(255, r);
|
|
assertEquals(255, g);
|
|
assertEquals(255, b);
|
|
}
|
|
|
|
@Test
|
|
public void testFormat3Bitstream() {
|
|
ProgramSymbolManager manager = new ProgramSymbolManager();
|
|
|
|
// Format 3 payload
|
|
// byte 0: 0x03 (Format 3)
|
|
// byte 1: LCID (0x44)
|
|
// byte 2: code point (0x43)
|
|
// byte 3: RWS (2)
|
|
// followed by (9 * 16 + 7) / 8 = 18 bytes
|
|
byte[] payload = new byte[4 + 18];
|
|
payload[0] = 0x03; // Format 3
|
|
payload[1] = 0x44; // LCID 0x44
|
|
payload[2] = 0x43; // Code point 0x43
|
|
payload[3] = 0x02; // RWS 2
|
|
payload[4] = (byte) 0x80; // First pixel is set
|
|
|
|
manager.loadps(payload);
|
|
|
|
ProgramSymbolSet set = manager.getSymbolSet(0x44);
|
|
assertNotNull(set);
|
|
ProgramSymbolSet.SymbolSlot slot = manager.getSymbol(0x44, 0x43);
|
|
assertNotNull(slot);
|
|
assertEquals(1, slot.getPixelData()[0]);
|
|
}
|
|
}
|