早期 J2ME 設備內存極受限,內置字體往往不支援中文或字體單一。將常用漢字的點陣字模(12×12、16×16、24×24、48×48、64×64 等)以十六進制數組硬編碼進程式,再用 Graphics.drawLine() 逐像素繪製,成為當時實現中文顯示的主流方案。
以 16×16 宋體「宋」字為例,佔 32 byte(16 行 × 2 byte/行):
char song16[] = {
0x02, 0x00, 0x01, 0x00, 0x7F, 0xFE, 0x41, 0x04,
0x81, 0x08, 0x01, 0x00, 0x7F, 0xFC, 0x03, 0x80,
0x05, 0x80, 0x05, 0x40, 0x09, 0x20, 0x11, 0x10,
0x21, 0x0E, 0x41, 0x04, 0x01, 0x00, 0x00, 0x00
};
每行 16 想素 → 2 byte(高位在前)。第 j 行、第 i 字節的第 k 位(0x80 >> k)為 1 表示該像素點亮。
void drawmat(char[] mat, Graphics g, int matsize, int x, int y, int color) {
int n = (matsize - 1) / 8 + 1; // 每行佔用的字節數
for (int j = 0; j < matsize; j++) { // 遍歷行
for (int i = 0; i < n; i++) { // 遍歷每行的字節
for (int k = 0; k < 8; k++) { // 遍歷字節內 8 位
if ((mat[j * n + i] & (0x80 >> k)) != 0) {
g.drawLine(x + i * 8 + k, y + j, x + i * 8 + k, y + j); // 畫單像素
}
}
}
}
}
public class FontMIDlet extends MIDlet {
protected void startApp() {
Display.getDisplay(this).setCurrent(new FontCanvas());
}
// ... 字模數組定義 ...
class FontCanvas extends Canvas {
protected void paint(Graphics g) {
g.setColor(0x0);
g.fillRect(0, 0, getWidth(), getHeight());
drawFont(g); // 依次調用 drawmat 繪製各字
}
}
}
MutableImage 緩存,繪製時直接 drawImage,大幅提升幀率。/res/font.dat,運行時讀取,減小類文件體積,便於動態更新字庫。點陣字庫技術雖屬「遠古」方案,但其「位操作 + 逐像素繪製」的核心邏輯在嵌入式圖形、電子墨水屏驅動、微型顯示器開發中依然通用。理解其原理有助於掌握底層字體渲染管線。