Computing stuff tied to the physical world

Posts Tagged ‘Graphics’

Gravity + Pressure + GLCD

In Software on Jun 2, 2012 at 00:01

For those interested in the above combination, I’ve added a little demo combining the Gravity Plug, Pressure Plug, and Graphics Board – oh and a JeeNode of course (it’s actually an experimental JeeNode USB v4 …):

DSC 3310

The display shows the current X, Y, and Z accelerometer values as raw readings, plus temperature and pressure:

DSC 3313

Both plugs use I2C, and could have been combined on one port. Note that the backlight is off in this example.

The sketch is called – somewhat presumptuouslyglcd_imu.ino. And it’s now on GitHub, as part of GLCDlib:

Screen Shot 2012 05 29 at 13 33 02

The GraphicsBoard class extends the GLCD_ST7565 class with print(…) calls and could be useful in general.

Get the GitHub version to see the details – omitted here for brevity.

Font tables – proportional

In Software on Jun 7, 2011 at 00:01

Unlike monospaced font tables, proportional fonts have character glyphs which all differ in size and relative positioning. This not only requires more storage, it also complicates the way these glyphs are stored in the bitmap image in flash memory.

In the GLCD library, I implemented this by storing two bytes for each character:

  • P: the horizontal start position of the glyph in the image (1 byte)
  • A: same as for monospaced fonts, but per-character pre-gap (4 bits)
  • B: same as for monospaced fonts, but per-character post-gap (4 bits)

The width of a glyph can be found by looking at the position of the next character glyph in the bitmap, which is placed right next to it.

Here is an example of a small proportional font:

Screen Shot 2011 06 01 at 17.24.37

I removed some parts for brevity.

So the “!” exclamation point for example, has width 2 in the bitmap (i.e. 3-1), with pre- and post-gaps of both 1 (i.e. 5-4). And the “#” numbersign charcter uses kerning, with a -1 pre-gap.

There is a problem, however. Most characters are fine, but after the “S”, the bit map position increments to a value greater than 255, which can’t be represented in a single byte!

Instead of doubling the position to use 2 bytes each, I implemented an “overflow” mechanism. This saves some memory, since most positions are just fine, if we ignore the top byte. We merely need to keep track of those few character positions where overflow actually happens.

This is what the “overflow position table” at the end does: for each character which straddles a 256-pixel boundary, it stores the offset of that character in the table. The result is that there is now sufficient info to locate each glyph, and this process only requires a few flash memory reads for any character code.

Note that for consistency, there are also two sentinels: one at the end of the per-character info, so that the width of that last character can be computed, and another one at the very end, to simplify the overflow calculation logic.

So there you have it: full font support, which easily fits in an ATmega!

Font tables – monospaced

In Software on Jun 6, 2011 at 00:01

The font support added yesterday works with compact byte tables stored in flash ROM to store all the “glyphs”, i.e. pre-computed bitmaps.

Here’s the entire table of the clR6x8 font:

Screen Shot 2011 06 01 at 16.31.53

All the characters are stored side-by-side in a very wide horizontal bitmap image. In this case, the height is 8 pixels and the width = 72 x 8 = 572 pixels.

In detail:

  • H: the height of the image, in pixels (1 byte)
  • W: the width of the image, in bytes (1 byte)
  • the image data, 8 horizontal bits per byte (H x W bytes)
  • F: the code of the first character stored for this font (1 byte)
  • N: the number of consecutive characters in this font (1 byte)

And then it depends on whether the font is monospaced or proportional. For a mono-spaced font, i.e. where all the glyphs have the same size:

  • P: the number of horizontal pixels per glyph (1 byte)
  • A: the “pre-gap” (value -4..11, encoded as 4 bits by adding 4 to it)
  • B: the “post-gap” (value -4..11, encoded as 4 bits by adding 4 to it)

The pre-gap defines where to start copying the glyph, relative to the current horizontal position. A negative value causes kerning. Likewise, the post-gap indicates where to start writing the next character. IOW, after a character has been processed, the horizontal position is advanced by P + B pixels (A does not participate in this calculation).

Proportional fonts

In Software on Jun 5, 2011 at 00:01

The GLCDlib library for the Graphics Board has been extended to support multiple fonts!

Dsc 2568

If you look closely, you’ll see that even kerning has been implemented – making italics much nicer.

The main use I see for this is not so much about going overboard with all sort of “roman”, “italic”, or “bold” mixes (although now you can), but to mix different font sizes on the same screen (large values, small labels, etc).

Here’s the new font_demo.pde sketch which produces the above display:

Screen Shot 2011 06 06 at 17.36.02

That’s just 7 of the 250+ fonts and variations now present in the GLCD library :)

To use a font, include the proper header in your sketch, and call glcd.setFont() to activate it. The thing to keep in mind is that fonts use up flash memory space. I’ve come up with a fairly compact way to store them, but larger fonts obviously need more memory than tiny ones, especially if they include all ASCII character codes. Also, proportional fonts need more space than mono-spaced fonts, due to extra per-character width / offset info.

Here is an overview of the amount of memory needed for each font, sorted by size:

    246   micro
    294   4x6
    294   clR4x6
    366   clR5x6
    426   5x7
    438   clR6x6
    486   5x8
    486   clR5x8
    582   clR6x8
    606   clR5x10
    7099  helvBO24
    7165  charB24
    7240  ncenI24
    7376  lubB24
    7478  lubI24
    7529  charBI24
    7595  ncenBI24
    7762  luBS24
    8148  lubBI24
    8627  luBIS24

The above sketch compiles to 12572 bytes, of which about 8 Kb are fonts.

One last note: these changes mean that you now always have to set up some font before calling drawChar() or drawString(), there is no default (it might not be the one you want, or you might not need any fonts at all).