Question

I need a compact data structure for an embedded system in C. Given a byte representing an ascii code, a function will return a 6-byte bitmap for that font's character. Only a few characters' bitmaps will be in ROM - for example, 0-9, '.', ':', and some others.

One inefficient solution would be to have an array with a length equal to the highest Ascii value which points to an index in a second array that stores the character bitmaps. For example the first array would have 128 elements of one byte, and if I have 20 characters' bitmaps defined, the second array would have 20 elements of 6 bytes. The element values in the first array would map to the index in the second array so an ascii value selects the element in the first array, and that element's value is used as the index value in the second array to get the 6-byte bitmap. But this wastes about 100 bytes (in the first array).

Is there a better way? Thanks

Edit: I'm thinking I'm going to have to use a switch statement or similar - such as @Brandon Yates's suggestion, I'm probably nit picking

Was it helpful?

Solution

What about just an array of structures like

typedef struct
{
    uint8_t asciiCode;
    uint8_t bitmap;
} charMapping_t;

Then initialize it like

const static charMapping_t myMap[20] = {your 20 chars....}

OTHER TIPS

So something like the following is not efficient enough:

struct bitmap {
    char byte[6];
};

char charset[] = "0123456789+-*/;.";

/* initialize the glyphs in the same order as charset, use glyph[0] for unknown ascii */
const struct bitmap map[sizeof(charset)+1] = { 
    { }, /* unknown glyph */
    { }, /* glyph for 0 */
    { }, /* glyph for 1 */
    ...
    { }, /* glyph for + */
    { }, /* glyph for - */
    ...
    { }, /* glyph for . */
};

/* return the appropriate map */
static inline const struct bitmap const * get_bitmap(char ascii) {
      char *p = strchr(charset, ascii);
      if ( p ) {  return &map[(p - charset) + 1]; }
      return &map[0];
}

For 12 bytes, you can store a bitmask where bit n is 1 if you've got a graphical bitmap for character n (where 32 <= n < 128). Store your bitmaps packed in a byte array (be careful using structs, because you may have to worry about padding between elements).

Your code will look something like this. The get_bitmap code is naive and slow but will compile to something small.

const unsigned char bitmap_available[12] = {0x1, 0x23, ...};
const unsigned char bitmaps[] = {
    0x0, 0xff, 0x0, 0xff, 0x0, 0xff,  // first character
    0x1, 0x1, 0x1, 0x1, 0x1, 0x1, // second character
    ...
};

/* Do we have bitmap data available for character c? */
int char_available(char c) {
    if (c < 32 || c > 127) return 0;
    c -= 32;
    return (bitmap_available[c >> 3] >> (c & 7)) & 1;
}

/* Returns pointer to bitmap for character c, or NULL if it's not present. */
const unsigned char *get_bitmap(char c) {
    int i, n = 0;
    if (!char_available(c)) return 0;
    for (i = 32; i < c; i++) {
        n += char_available(i);
    }
    return bitmaps + n * 6;
}

Obviously I don't know which characters you want, nor do I have your bitmaps, so I put some random data in the two data arrays as an example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top