📄 font.java
字号:
// set the charset, either the specified or the entire one
if(charset != null) this.charset = charset;
else {
this.charset = new char[fullCharset.length];
System.arraycopy(fullCharset,0,this.charset,0,fullCharset.length);
}
this.images = new Image[this.charset.length];
// sort the charset (a binary search will be used later)
for(int i=0; i<this.charset.length ;i++)
for(int j=i+1; j<this.charset.length ;j++)
if(this.charset[j] < this.charset[i]) {
final char t = this.charset[i];
this.charset[i] = this.charset[j];
this.charset[j] = t;
}
// load each char's image
for(int i=0; i<charsetLength ;i++) {
// the original image's width
final int width = dis.readByte();
// if there's an specific charset, check if this char is required
// otherwise, skip its data
if(charset != null) {
boolean skip = true;
for(int c=0; c<charset.length ;c++)
if(charset[c] == fullCharset[i]) { skip = false; break; }
if(skip) { dis.skipBytes(width*maxh); continue; }
}
byte[] raw = new byte[width*maxh];
dis.readFully(raw);
// if there's a resizing...
if(size != 0 && size != maxh) {
final int newWidth = (size * width) / maxh;
raw = _resize(raw,maxh,size);
this.images[_getIndex(fullCharset[i])] = _createRaw(newWidth,size,raw,color);
}
else this.images[_getIndex(fullCharset[i])] = _createRaw(width,maxh,raw,color);
}
dis.close();
final int correct = 0; // not implemented yet
this.size = ((size != 0)? size : maxh) + correct;
spaceWidth = this.size/2;
grey_pal = null; // free the array memory (setted durning _createRaw)
}
final private int _getWidth(char c) {
if(c == ' ') return spaceWidth;
switch(type) {
case TYPE_MAPPED: return images[_getIndex(c)].getWidth();
case TYPE_STRIP: return widths[_getIndex(c)];
default:
return 0; // TODO throw exception
}
}
final private int _getWidth(final String s) {
if(s.length() == 0) return 0;
int len = 0;
for(int i=0; i<s.length() ;i++)
len += _getWidth(s.charAt(i)) + charSpacing;
if(s.length() > 0) len -= charSpacing;
return len;
}
final private void _write(final Graphics g, final String s, int x, int y, int anchor) {
int cx=0, cy=0, cw=0, ch=0;
if(type == TYPE_STRIP) {
cx = g.getClipX();
cy = g.getClipY();
cw = g.getClipWidth();
ch = g.getClipHeight();
}
if((anchor & Graphics.RIGHT) != 0) {
for(int i=s.length()-1; i>= 0 ;i--) {
if(s.charAt(i) == ' ') x -= (spaceWidth + charSpacing);
else {
final int index = _getIndex(s.charAt(i));
if(type == TYPE_MAPPED) {
final Image image = images[index];
x -= image.getWidth();
g.drawImage(image, x, y, 0);
}
else {
x -= widths[index];
g.setClip(x, y, widths[index], size);
g.drawImage(strip, x-offsets[index], y-0, 0);
g.setClip(cx, cy, cw, ch);
}
x -= charSpacing;
}
}
}
else if((anchor & Graphics.HCENTER) != 0) {
final int w = getWidth(s)/2;
for(int i=0; i<s.length() ;i++) {
if(s.charAt(i) == ' ') x += spaceWidth + charSpacing;
else {
final int index = _getIndex(s.charAt(i));
if(type == TYPE_MAPPED) {
final Image image = images[index];
g.drawImage(image, x-w, y, 0);
x += image.getWidth() + charSpacing;
}
else {
g.setClip(x-w, y, widths[index], size);
g.drawImage(strip, x-offsets[index]-w, y-0, 0);
x += widths[index] + charSpacing;
g.setClip(cx, cy, cw, ch);
}
}
}
}
else if((anchor & Graphics.LEFT) != 0 || anchor == 0) {
for(int i=0; i<s.length() ;i++) {
if(s.charAt(i) == ' ') x += spaceWidth + charSpacing;
else {
final int index = _getIndex(s.charAt(i));
if(type == TYPE_MAPPED) {
final Image image = images[index];
g.drawImage(image, x, y, 0);
x += image.getWidth() + charSpacing;
}
else {
g.setClip(x, y, widths[index], size);
g.drawImage(strip, x-offsets[index], y-0, 0);
x += widths[index] + charSpacing;
g.setClip(cx, cy, cw, ch);
}
}
}
}
else throw new IllegalArgumentException();
}
final static private byte[] _resize(byte[] raw, int height, int newHeight) {
final int width = raw.length/height;
final int newWidth = (newHeight * width) / height;
final byte[] out = new byte[newWidth * newHeight];
for(int y = 0; y < newHeight; y++) {
final int dy = y * height / newHeight;
final int nw = newWidth*y;
final int ow = width*dy;
for(int x = 0; x < newWidth; x++)
out[nw + x] = raw[ow + (x*width / newWidth)];
}
return out;
}
// ==============================================
// Raw image PNG encoder optimized for MicroFonts
// ==============================================
static private final int[] crc_table;
static private int[] grey_pal;
static private final byte[] trans_pal;
static {
crc_table = new int[256];
for(int i=0; i<256 ;i++) {
int c = i;
for(int k=8; --k>= 0;)
c = ((c & 1) != 0)? 0xedb88320 ^ (c >>> 1) : c >>> 1;
crc_table[i] = c;
}
trans_pal = new byte[256];
for(int i=0; i<256; i++)
trans_pal[i] = (byte) ((i % 16) * 16);
}
final static private Image _createRaw(int width, int height, final byte[] raw, int color) {
final int size = 256*3 + 256 + (width+1)*height + 93; // palette * 3 + trans (256) + w*h + chunk stuff
final byte[] data = new byte[size];
// PNG file signature
data[0] = -119;
data[1] = 0x50;
data[2] = 0x4e;
data[3] = 0x47;
data[4] = 0x0d;
data[5] = 0x0a;
data[6] = 0x1a;
data[7] = 0x0a;
// Header 'IHDR' Chunk
data[11] = 0x0d; // Chunk length: 4b (13 bytes)
_wint(0x49484452, data, 12); // Chunk Name 'IHDR'
data[19] = (byte) width; // Width: 4b
data[23] = (byte) height; // Height: 4b
data[24] = 0x08; // Bitdepth
data[25] = 0x03; // Color Type (RGB + A)
// data[26] = 0x00; // Compression method
// data[27] = 0x00; // Filter method
// data[28] = 0x00; // Interlace method
_wint(_crc(data, 12, 17), data, 29);
// Palette 'PLTE' Chunk
_wint(256 * 3, data, 33); // Chunk length
_wint(0x504c5445, data, 37); // Chunk Name 'PLTE'
if(grey_pal == null) {
grey_pal = new int[256];
for(int i=0; i<256; i++)
grey_pal[i] = ((i / 17) << 4);
}
for(int i=0, c=41; i<256; i++) {
final int grey = grey_pal[i];
data[c++] = (byte) ((grey * ((color & 0x00FF0000) >> 16)) >> 8);
data[c++] = (byte) ((grey * ((color & 0x0000FF00) >> 8)) >> 8);
data[c++] = (byte) ((grey * ((color & 0x000000FF) >> 0)) >> 8);
}
_wint(_crc(data, 37, 809 - 37), data, 809);
// Transparency 'tRNS' Chunk
_wint(256 + 1, data, 813); // Chunk length
_wint(0x74524e53, data, 817); // 'tRNS' Header
System.arraycopy(trans_pal,0,data,821,256);
//data[1077] = 0; ??
_wint(_crc(data, 817, 1078 - 817), data, 1078);
// Image Data 'IDAT' Chunk
int compsize = (width + 1) * height;
_wint(compsize + 11, data, 1082); // Chunk Length
_wint(0x49444154, data, 1086); // Chunk Name 'IDAT'
data[1090] = (byte) 0x78; // PNG compression flags
data[1091] = (byte) 0xda; // PNG compression flags
data[1092] = (byte) 0x01; // PNG final block / No compression
data[1093] = (byte) (compsize & 0xff);
data[1094] = (byte) ((compsize >>> 8) & 0xff);
data[1095] = (byte) (~data[1095 - 2]);
data[1096] = (byte) (~data[1096 - 2]);
int p = 1097;
for(int y=0, i=0; y<height; y++) { // Data copy
p++;
System.arraycopy(raw, i, data, p, width);
p+=width;
i+=width;
}
int adler1 = 1;
int adler2 = 0;
for (int i = 0; i < compsize; i++) {
adler1 = adler1 + ((int) data[1097+ i] & 0xff);
adler2 = adler1 + adler2;
adler1 %= 65521;
adler2 %= 65521;
}
_wint((adler2 << 16) | adler1, data, p);
p += 4;
_wint(_crc(data, 1086, p - 1086), data, p);
p += 4;
// Footer 'IEND' Chunk
p += 4; // Four 0 bytes
data[p++] = (byte) 'I';
data[p++] = (byte) 'E';
data[p++] = (byte) 'N';
data[p++] = (byte) 'D';
data[p++] = -82;
data[p++] = 0x42;
data[p++] = 0x60;
data[p++] = -126;
return Image.createImage(data, 0, p);
}
final static private void _wint(long crc, byte[] d, int p) {
d[p+0] = (byte) ((crc >>> 24) & 255);
d[p+1] = (byte) ((crc >>> 16) & 255);
d[p+2] = (byte) ((crc >>> 8) & 255);
d[p+3] = (byte) (crc & 255);
}
final static private long _crc(byte[] buf, int off, int len) {
int c = ~0;
while(--len >= 0)
c = crc_table[(c ^ buf[off++]) & 0xff] ^ (c >>> 8);
return (long) ~c & 0xffffffffL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -