forked from kreativekorp/bitsnpicas
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
077d531
commit 1ed746d
Showing
7 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
main/java/BitsNPicas/src/com/kreative/bitsnpicas/exporter/FZXBitmapFontExporter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package com.kreative.bitsnpicas.exporter; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import com.kreative.bitsnpicas.BitmapFont; | ||
import com.kreative.bitsnpicas.BitmapFontExporter; | ||
import com.kreative.bitsnpicas.BitmapFontGlyph; | ||
|
||
public class FZXBitmapFontExporter implements BitmapFontExporter { | ||
@Override | ||
public byte[] exportFontToBytes(BitmapFont font) throws IOException { | ||
ByteArrayOutputStream os = new ByteArrayOutputStream(); | ||
exportFontToStream(font, os); | ||
os.close(); | ||
return os.toByteArray(); | ||
} | ||
|
||
@Override | ||
public void exportFontToStream(BitmapFont font, OutputStream os) throws IOException { | ||
int ascent = font.getLineAscent(); | ||
int height = ascent + font.getLineDescent(); | ||
int tracking = 255; | ||
int lastchar = 255; | ||
while (lastchar > 32 && !font.containsCharacter(zxcp(lastchar))) lastchar--; | ||
for (int ch = 32; ch <= lastchar; ch++) { | ||
BitmapFontGlyph g = font.getCharacter(zxcp(ch)); | ||
if (g != null) { | ||
int rsb = g.getCharacterWidth() - (g.getGlyphOffset() + g.getGlyphWidth()); | ||
if (rsb <= 0) { tracking = 0; break; } | ||
else if (rsb < tracking) tracking = rsb; | ||
} | ||
} | ||
if (height < 1) height = 1; | ||
if (height > 255) height = 255; | ||
|
||
int end = (lastchar - 30) * 3; | ||
int ptr = end + 2; | ||
int[] offset = new int[lastchar - 31]; | ||
int[] kern = new int[lastchar - 31]; | ||
int[] shift = new int[lastchar - 31]; | ||
int[] width = new int[lastchar - 31]; | ||
byte[][] cdef = new byte[lastchar - 31][]; | ||
for (int i = 0, ch = 32; ch <= lastchar; ch++, i++) { | ||
BitmapFontGlyph g = font.getCharacter(zxcp(ch)); | ||
if (g == null) { | ||
offset[i] = ptr; | ||
kern[i] = 0; | ||
shift[i] = 0; | ||
width[i] = 1; | ||
cdef[i] = new byte[0]; | ||
} else { | ||
int lsb = g.getGlyphOffset(); | ||
int tsb = ascent - g.getGlyphAscent(); | ||
int rsb = g.getCharacterWidth() - (lsb + g.getGlyphWidth()); | ||
offset[i] = ptr; | ||
kern[i] = (lsb <= -3) ? 3 : (lsb >= 0) ? 0 : -lsb; | ||
shift[i] = (tsb <= 0) ? 0 : (tsb >= 15) ? 15 : tsb; | ||
int kernExtra = lsb + kern[i]; | ||
int shiftExtra = tsb - shift[i]; | ||
int widthExtra = rsb - tracking; | ||
int zxw = g.getGlyphWidth() + kernExtra + widthExtra; | ||
int zxh = g.getGlyphHeight() + shiftExtra; | ||
int bpr = (zxw <= 8) ? 1 : 2; | ||
width[i] = (zxw <= 1) ? 1 : (zxw >= 16) ? 16 : zxw; | ||
cdef[i] = new byte[zxh * bpr]; | ||
boolean cdefChanged = false; | ||
byte[][] gd = g.getGlyph(); | ||
for (int gdy = -shiftExtra, cdy = 0, zxy = 0; zxy < zxh; zxy++, cdy += bpr, gdy++) { | ||
if (gdy >= 0 && gdy < gd.length) { | ||
for (int gdx = -kernExtra, cdx = 0x8000, zxx = 0; zxx < width[i]; zxx++, cdx >>= 1, gdx++) { | ||
if (gdx >= 0 && gdx < gd[gdy].length && gd[gdy][gdx] < 0) { | ||
if (cdx < 0x100) cdef[i][cdy + 1] |= cdx; | ||
else cdef[i][cdy] |= (cdx >> 8); | ||
cdefChanged = true; | ||
} | ||
} | ||
} | ||
} | ||
if (cdefChanged) { | ||
ptr += cdef[i].length; | ||
} else { | ||
kern[i] = 0; | ||
shift[i] = 0; | ||
cdef[i] = new byte[0]; | ||
} | ||
} | ||
} | ||
|
||
os.write(height); | ||
os.write(tracking); | ||
os.write(lastchar); | ||
for (int o = 3, i = 0, ch = 32; ch <= lastchar; ch++, i++, o += 3) { | ||
int ok = ((offset[i] - o) & 0x3FFF) | (kern[i] << 14); | ||
int sw = (shift[i] << 4) | ((width[i] - 1) & 0x0F); | ||
os.write(ok); | ||
os.write(ok >> 8); | ||
os.write(sw); | ||
} | ||
os.write(ptr - end); | ||
os.write((ptr - end) >> 8); | ||
for (byte[] cd : cdef) os.write(cd); | ||
} | ||
|
||
@Override | ||
public void exportFontToFile(BitmapFont font, File file) throws IOException { | ||
FileOutputStream os = new FileOutputStream(file); | ||
exportFontToStream(font, os); | ||
os.close(); | ||
} | ||
|
||
private int zxcp(int ch) { | ||
if (ch == 96) return 163; | ||
if (ch == 127) return 169; | ||
if (ch < 128) return ch; | ||
return (0xF000 + ch); | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
main/java/BitsNPicas/src/com/kreative/bitsnpicas/importer/FZXBitmapFontImporter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package com.kreative.bitsnpicas.importer; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import com.kreative.bitsnpicas.BitmapFont; | ||
import com.kreative.bitsnpicas.BitmapFontGlyph; | ||
import com.kreative.bitsnpicas.BitmapFontImporter; | ||
import com.kreative.bitsnpicas.Font; | ||
|
||
public class FZXBitmapFontImporter implements BitmapFontImporter { | ||
private static final char[] X_HEIGHT_CHARS = new char[]{'x', 'X', '0', '!'}; | ||
|
||
@Override | ||
public BitmapFont[] importFont(byte[] data) throws IOException { | ||
// HEADER | ||
if (data.length < 3) return new BitmapFont[0]; | ||
int height = data[0] & 0xFF; | ||
int tracking = data[1] & 0xFF; | ||
int lastchar = data[2] & 0xFF; | ||
if (lastchar < 32) return new BitmapFont[0]; | ||
|
||
// TABLE | ||
int end = (lastchar - 30) * 3; | ||
if (data.length < end + 2) return new BitmapFont[0]; | ||
int[] offset = new int[lastchar - 30]; | ||
int[] kern = new int[lastchar - 31]; | ||
int[] shift = new int[lastchar - 31]; | ||
int[] width = new int[lastchar - 31]; | ||
for (int o = 3, i = 0, ch = 32; ch <= lastchar; ch++, i++, o += 3) { | ||
int ok = (data[o] & 0xFF) | ((data[o + 1] & 0xFF) << 8); | ||
int sw = (data[o + 2] & 0xFF); | ||
offset[i] = (ok & 0x3FFF) + o; | ||
kern[i] = ok >> 14; | ||
shift[i] = sw >> 4; | ||
width[i] = (sw & 0x0F) + 1; | ||
} | ||
offset[lastchar - 31] = ((data[end] & 0xFF) | ((data[end + 1] & 0xFF) << 8)) + end; | ||
|
||
// CHARACTER DEFINITIONS | ||
byte[][][] gd = new byte[lastchar - 31][][]; | ||
for (int i = 0, ch = 32; ch <= lastchar; ch++, i++) { | ||
int bpr = ((width[i] <= 8) ? 1 : 2); | ||
int rows = (offset[i + 1] - offset[i]) / bpr; | ||
if (rows < 0) rows = 0; | ||
gd[i] = new byte[rows][width[i]]; | ||
for (int o = offset[i], y = 0; y < rows; y++, o += bpr) { | ||
int row = (o < data.length) ? ((data[o] & 0xFF) << 8) : 0; | ||
row |= (o + 1 < data.length) ? (data[o + 1] & 0xFF) : 0; | ||
for (int m = 0x8000, x = 0; x < width[i]; x++, m >>= 1) { | ||
if ((row & m) != 0) gd[i][y][x] = -1; | ||
} | ||
} | ||
} | ||
|
||
int ascent = height; | ||
int descent = 0; | ||
int xheight = 0; | ||
for (char x : X_HEIGHT_CHARS) { | ||
if (lastchar >= x) { | ||
byte[][] gdx = gd[x - 32]; | ||
xheight = gdx.length; | ||
ascent = shift[x - 32] + xheight; | ||
descent = height - ascent; | ||
break; | ||
} | ||
} | ||
|
||
BitmapFont f = new BitmapFont(ascent, descent, ascent, descent, xheight, 0); | ||
for (int i = 0, ch = 32; ch <= lastchar; ch++, i++) { | ||
int cp = ( | ||
(ch == 96) ? 163 : | ||
(ch == 127) ? 169 : | ||
(ch < 128) ? ch : | ||
(0xF000 + ch) | ||
); | ||
BitmapFontGlyph g = new BitmapFontGlyph( | ||
gd[i], -kern[i], | ||
width[i] - kern[i] + tracking, | ||
ascent - shift[i] | ||
); | ||
f.putCharacter(cp, g); | ||
} | ||
return new BitmapFont[]{f}; | ||
} | ||
|
||
@Override | ||
public BitmapFont[] importFont(InputStream in) throws IOException { | ||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
byte[] buf = new byte[1048576]; int read; | ||
while ((read = in.read(buf)) >= 0) out.write(buf, 0, read); | ||
out.close(); | ||
return importFont(out.toByteArray()); | ||
} | ||
|
||
@Override | ||
public BitmapFont[] importFont(File file) throws IOException { | ||
FileInputStream in = new FileInputStream(file); | ||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
byte[] buf = new byte[1048576]; int read; | ||
while ((read = in.read(buf)) >= 0) out.write(buf, 0, read); | ||
out.close(); | ||
in.close(); | ||
BitmapFont[] f = importFont(out.toByteArray()); | ||
if (f.length > 0) { | ||
String name = file.getName(); | ||
if (name.toLowerCase().endsWith(".fzx")) { | ||
name = name.substring(0, name.length() - 4); | ||
} | ||
for (BitmapFont ff : f) { | ||
ff.setName(Font.NAME_FAMILY, name); | ||
} | ||
} | ||
return f; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters