3

An E Ink display I bought supports displaying text using a built-in command. According to the documentation, it also allows me to load a different "font library" for Chinese characters:

Font libraries

The system built-in 32, 48 and 64 dots English font is always available without using the TF card or the NandFlash; however, for the 32, 48 and 64 dots Chinese font, you should store the relative library file to the TF card or the NandFlash before using it.

I found a sample of one of these font files in a GitHub library for this display: GBK32.FON, GBK48.FON and GBK64.FON.

Unfortunately, this is as far as I got.

  • file produces nothing useful (GBK32.FON: data)

  • FontForge just gives me an error: GBK32.FON is not in a known format (or uses features of that format fontforge does not support, or is so badly corrupted as to be unreadable)

  • TrID outputs 100.0% (.ABR) Adobe PhotoShop Brush (1002/3), however I failed to open the files in Photoshop

  • PSFTools doesn't recognise it as a valid Windows .FON or .FNT file

  • A hex editor shows there's no magic number - in fact, the first 15 bytes in all three files are just zeroes

  • Based on the size of the files, it appears the files are some kind of bitmaps (size of GBK32.FON / 32^2 = size of GBK48.FON / 48^2 = size of GBK64.FON / 64^2)

Is there any "known" bitmap font that might fit this description? What else could I try to figure this format out?

4
  • trid might be worth trying
    – Journeyman Geek
    Commented Jun 8, 2017 at 23:00
  • Thanks, just tried - it recognised GBK32.FON as an Adobe Brush (ABR) files. Photoshop disagrees though. Will edit post.
    – fstanis
    Commented Jun 8, 2017 at 23:04
  • There are patterns visible in the ASCII view of the file. Definitely looks bitmap-ish.
    – gronostaj
    Commented Jun 8, 2017 at 23:13
  • Good catch! After a lot more googling, I may have found something similar: font24.c
    – fstanis
    Commented Jun 8, 2017 at 23:16

2 Answers 2

4

I assumed that characters are black-and-white bitmaps of constant dimensions. The most primitive encoding would be to store every 8 consecutive pixels as bits in a single byte. It's simple, not very performance-demanding and has the big advantage of all characters being the same number of bytes long, so you can predictably jump to whatever character you need.

I've hacked a simple Python script to test these assumptions. It processes these files, replacing every byte with 8-character strings consisting of (space) and # respectively for 0 and 1 bits in big endian order. That makes output files viewable in any text editor that can handle files such large. Here's the code and here's the processed GBK32.FON with line wrapping set to 32 characters:

Clearly visible glyph of a character composed of #s

As you might have guessed, the glyph is 32 pixels high.

2
  • Thank уоu, this is exactly how it works! In fact, the file contains exactly 23940 glyphs which matches the number of code points in the GBK range. With some playing around, I was able to create a .FON version of FontAwesome, so here's a somewhat unconventional form of thanks (the SO logo is a font character from my new font).
    – fstanis
    Commented Jun 10, 2017 at 16:39
  • @fstanis That's the most unique way of saying "thanks" I've seen around here :D Glad I could help!
    – gronostaj
    Commented Jun 11, 2017 at 12:02
1

My goodness! I went to ask for help but a tip box popped up saying avoid asking for help... hehe so, three days later I've done it myself so I thought i'd share a few extra tips.

Pulling the file into Java is pretty easy.

To import the Glyphs use (pseudocode),

BufferedInputStream bf = new BufferedInputStream(importGBKFileStream);

byte glyphline[] = new byte[glyphBitWith/8];  // 64 for GBK 64

while (bf.available() > 0) {

bf.read(glyphline);
for(int i = 0 ; i < glyphline.length ; i++){

String s = ("0000000" + Integer.toBinaryString(0xFF & glyphline[i])).replaceAll(".*(.{8})$", "$1");

... etc

To display the glyphs on the EPD

After some playing around, You need to send two Bytes to the EPD for each character. These characters start at (upper Byte) 0x81, (lower Byte) 0x40.

This is a good reference, https://en.wikipedia.org/wiki/GBK to see how the GBK data set is laid out. Another helpful reference are these https://r12a.github.io/apps/encodings/

Creating a custom font (pseudocode)

Download a .ttf file.and open it in java

    Font font = Font.createFont(Font.TRUETYPE_FONT, inttf);
    font = font.deriveFont((float) 64); 

    // for all characters in ASCII table

    text = Character.toString(chara);

    img = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_BYTE_BINARY);
    g2d = img.createGraphics();

    g2d.setColor(Color.BLACK);
    g2d.fillRect(0, 0, imageWidth, imageHeight);
    g2d.setColor(Color.WHITE);
    g2d.setFont(font);
    fm = g2d.getFontMetrics();

    // for all ascii values 0 - 256,  xpos
    g2d.drawString(text, 0, fm.getAscent());

    // use the character and the derrived with from the FontMetrics to
    // create a map for spacing the text manually                         
    characterWidthLogger(chara, textWidth);

    // should have the image as a dataByte buffer
    WritableRaster raster = img.getRaster();
    DataBufferByte data   = (DataBufferByte) raster.getDataBuffer();

    // output the data to a file or screen                                 
    displayByteArray(data ,imageHeight, imageWidth);

The characterWidthLogger() is important. On the micro that controlls the EPD I use the characterWidth map to set the spacing as. Therefor a "Text" command becomes 4 seperate commands ((x0, y0, "T"),(x0 + width 'T", y0 "e") etc.) and each character then gets converted to the chinese format. As to where you place the glyphs within your GBK files is up to you. The epd only allows the three file GBK32, GBK48, and GBK64. I copied over the chinese glyps at the start upper 0x81, lower 0x80. So T which is ascii 0x54 becomes 0x81, 0xD4.

Hope it helps

Hayden

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .