Demo of GP9002 VFD in grayscale mode
Dependencies: Adafruit-GFX-Library-master Adafruit-GP9002-Grayscale-VFD-Library mbed
Fork of GP9002adafruit by
Revision 1:3b26acd91611, committed 2016-05-02
- Comitter:
- oliverb
- Date:
- Mon May 02 16:49:40 2016 +0000
- Parent:
- 0:414a9e6fed37
- Child:
- 2:efef4231b922
- Commit message:
- Adafruit_GFX appears to compile, looks as if it is a stream-ish object, but "print" is undefined and looks like it might be "puts"; ; I've given up on preserving Arduino headers;
Changed in this revision
--- a/Adafruit-GFX-Library-master/Adafruit_GFX.cpp Mon May 02 11:24:17 2016 +0000 +++ b/Adafruit-GFX-Library-master/Adafruit_GFX.cpp Mon May 02 16:49:40 2016 +0000 @@ -31,11 +31,6 @@ POSSIBILITY OF SUCH DAMAGE. */ -#ifdef __AVR__ - #include <avr/pgmspace.h> -#elif defined(ESP8266) - #include <pgmspace.h> -#endif #include "Adafruit_GFX.h" #include "glcdfont.c" @@ -466,12 +461,7 @@ } } -#if ARDUINO >= 100 -size_t Adafruit_GFX::write(uint8_t c) { -#else -void Adafruit_GFX::write(uint8_t c) { -#endif - +int Adafruit_GFX::_putc(int c) { if(!gfxFont) { // 'Classic' built-in font if(c == '\n') { @@ -516,10 +506,15 @@ } } -#if ARDUINO >= 100 return 1; -#endif } +// get a single character (Stream implementation) +int Adafruit_GFX::_getc() { + return -1; +} + + + // Draw a character void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, @@ -639,7 +634,7 @@ textbgcolor = b; } -void Adafruit_GFX::setTextWrap(boolean w) { +void Adafruit_GFX::setTextWrap(bool w) { wrap = w; } @@ -670,7 +665,7 @@ // with the erroneous character indices. By default, the library uses the // original 'wrong' behavior and old sketches will still work. Pass 'true' // to this function to use correct CP437 character values in your code. -void Adafruit_GFX::cp437(boolean x) { +void Adafruit_GFX::cp437(bool x) { _cp437 = x; } @@ -690,7 +685,7 @@ } // Pass string and a cursor position, returns UL corner and W,H. -void Adafruit_GFX::getTextBounds(char *str, int16_t x, int16_t y, +void Adafruit_GFX::getTextBounds(const char *str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) { uint8_t c; // Current character @@ -779,6 +774,7 @@ } // Same as above, but for PROGMEM strings +/* void Adafruit_GFX::getTextBounds(const __FlashStringHelper *str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) { uint8_t *s = (uint8_t *)str, c; @@ -866,7 +862,7 @@ } // End classic vs custom font } - +*/ // Return the size of the display (per current rotation) int16_t Adafruit_GFX::width(void) const { return _width; @@ -876,7 +872,7 @@ return _height; } -void Adafruit_GFX::invertDisplay(boolean i) { +void Adafruit_GFX::invertDisplay(bool i) { // Do nothing, must be subclassed if supported by hardware } @@ -905,7 +901,7 @@ _label[9] = 0; } -void Adafruit_GFX_Button::drawButton(boolean inverted) { +void Adafruit_GFX_Button::drawButton(bool inverted) { uint16_t fill, outline, text; if(!inverted) { @@ -924,23 +920,23 @@ _gfx->setCursor(_x - strlen(_label)*3*_textsize, _y-4*_textsize); _gfx->setTextColor(text); _gfx->setTextSize(_textsize); - _gfx->print(_label); + _gfx->puts(_label); } -boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) { +bool Adafruit_GFX_Button::contains(int16_t x, int16_t y) { if ((x < (_x - _w/2)) || (x > (_x + _w/2))) return false; if ((y < (_y - _h/2)) || (y > (_y + _h/2))) return false; return true; } -void Adafruit_GFX_Button::press(boolean p) { +void Adafruit_GFX_Button::press(bool p) { laststate = currstate; currstate = p; } -boolean Adafruit_GFX_Button::isPressed() { return currstate; } -boolean Adafruit_GFX_Button::justPressed() { return (currstate && !laststate); } -boolean Adafruit_GFX_Button::justReleased() { return (!currstate && laststate); } +bool Adafruit_GFX_Button::isPressed() { return currstate; } +bool Adafruit_GFX_Button::justPressed() { return (currstate && !laststate); } +bool Adafruit_GFX_Button::justReleased() { return (!currstate && laststate); } // -------------------------------------------------------------------------
--- a/Adafruit-GFX-Library-master/Adafruit_GFX.h Mon May 02 11:24:17 2016 +0000 +++ b/Adafruit-GFX-Library-master/Adafruit_GFX.h Mon May 02 16:49:40 2016 +0000 @@ -1,16 +1,11 @@ #ifndef _ADAFRUIT_GFX_H #define _ADAFRUIT_GFX_H -#if ARDUINO >= 100 - #include "Arduino.h" - #include "Print.h" -#else - #include "WProgram.h" -#endif +#include "mbed.h" #include "gfxfont.h" -class Adafruit_GFX : public Print { +class Adafruit_GFX : public Stream { public: @@ -28,7 +23,7 @@ drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), fillScreen(uint16_t color), - invertDisplay(boolean i); + invertDisplay(bool i); // These exist only with Adafruit_GFX (no subclass overrides) void @@ -62,19 +57,27 @@ setTextColor(uint16_t c), setTextColor(uint16_t c, uint16_t bg), setTextSize(uint8_t s), - setTextWrap(boolean w), + setTextWrap(bool w), setRotation(uint8_t r), - cp437(boolean x=true), + cp437(bool x=true), setFont(const GFXfont *f = NULL), - getTextBounds(char *string, int16_t x, int16_t y, - int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h), - getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, + getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); - -#if ARDUINO >= 100 - virtual size_t write(uint8_t); -#else - virtual void write(uint8_t); +/* getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, + int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h); */ +#if DOXYGEN_ONLY + /** Write a character to the LCD + * + * @param c The character to write to the display + */ + int putc(int c); + + /** Write a formatted string to the LCD + * + * @param format A printf-style format string, followed by the + * variables to use in formatting the string. + */ + int printf(const char* format, ...); #endif int16_t height(void) const; @@ -97,11 +100,15 @@ uint8_t textsize, rotation; - boolean + bool wrap, // If set, 'wrap' text at right edge of display _cp437; // If set, use correct CP437 charset (default is off) GFXfont *gfxFont; +// Stream implementation functions + virtual int _putc(int value); + virtual int _getc(); + }; class Adafruit_GFX_Button { @@ -111,13 +118,13 @@ void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y, uint8_t w, uint8_t h, uint16_t outline, uint16_t fill, uint16_t textcolor, char *label, uint8_t textsize); - void drawButton(boolean inverted = false); - boolean contains(int16_t x, int16_t y); + void drawButton(bool inverted = false); + bool contains(int16_t x, int16_t y); - void press(boolean p); - boolean isPressed(); - boolean justPressed(); - boolean justReleased(); + void press(bool p); + bool isPressed(); + bool justPressed(); + bool justReleased(); private: Adafruit_GFX *_gfx; @@ -127,16 +134,16 @@ uint16_t _outlinecolor, _fillcolor, _textcolor; char _label[10]; - boolean currstate, laststate; + bool currstate, laststate; }; class GFXcanvas1 : public Adafruit_GFX { public: GFXcanvas1(uint16_t w, uint16_t h); - ~GFXcanvas1(void); - void drawPixel(int16_t x, int16_t y, uint16_t color), - fillScreen(uint16_t color); + virtual ~GFXcanvas1(void); + virtual void drawPixel(int16_t x, int16_t y, uint16_t color), + fillScreen(uint16_t color); uint8_t *getBuffer(void); private: uint8_t *buffer; @@ -144,9 +151,9 @@ class GFXcanvas16 : public Adafruit_GFX { GFXcanvas16(uint16_t w, uint16_t h); - ~GFXcanvas16(void); - void drawPixel(int16_t x, int16_t y, uint16_t color), - fillScreen(uint16_t color); + virtual ~GFXcanvas16(void); + virtual void drawPixel(int16_t x, int16_t y, uint16_t color), + fillScreen(uint16_t color); uint16_t *getBuffer(void); private: uint16_t *buffer;
--- a/Adafruit-GFX-Library-master/fontconvert/fontconvert.c Mon May 02 11:24:17 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,278 +0,0 @@ -/* -TrueType to Adafruit_GFX font converter. Derived from Peter Jakobs' -Adafruit_ftGFX fork & makefont tool, and Paul Kourany's Adafruit_mfGFX. - -NOT AN ARDUINO SKETCH. This is a command-line tool for preprocessing -fonts to be used with the Adafruit_GFX Arduino library. - -For UNIX-like systems. Outputs to stdout; redirect to header file, e.g.: - ./fontconvert ~/Library/Fonts/FreeSans.ttf 18 > FreeSans18pt7b.h - -REQUIRES FREETYPE LIBRARY. www.freetype.org - -Currently this only extracts the printable 7-bit ASCII chars of a font. -Will eventually extend with some int'l chars a la ftGFX, not there yet. -Keep 7-bit fonts around as an option in that case, more compact. - -See notes at end for glyph nomenclature & other tidbits. -*/ - -#include <stdio.h> -#include <ctype.h> -#include <stdint.h> -#include <ft2build.h> -#include FT_GLYPH_H -#include "../gfxfont.h" // Adafruit_GFX font structures - -#define DPI 141 // Approximate res. of Adafruit 2.8" TFT - -// Accumulate bits for output, with periodic hexadecimal byte write -void enbit(uint8_t value) { - static uint8_t row = 0, sum = 0, bit = 0x80, firstCall = 1; - if(value) sum |= bit; // Set bit if needed - if(!(bit >>= 1)) { // Advance to next bit, end of byte reached? - if(!firstCall) { // Format output table nicely - if(++row >= 12) { // Last entry on line? - printf(",\n "); // Newline format output - row = 0; // Reset row counter - } else { // Not end of line - printf(", "); // Simple comma delim - } - } - printf("0x%02X", sum); // Write byte value - sum = 0; // Clear for next byte - bit = 0x80; // Reset bit counter - firstCall = 0; // Formatting flag - } -} - -int main(int argc, char *argv[]) { - int i, j, err, size, first=' ', last='~', - bitmapOffset = 0, x, y, byte; - char *fontName, c, *ptr; - FT_Library library; - FT_Face face; - FT_Glyph glyph; - FT_Bitmap *bitmap; - FT_BitmapGlyphRec *g; - GFXglyph *table; - uint8_t bit; - - // Parse command line. Valid syntaxes are: - // fontconvert [filename] [size] - // fontconvert [filename] [size] [last char] - // fontconvert [filename] [size] [first char] [last char] - // Unless overridden, default first and last chars are - // ' ' (space) and '~', respectively - - if(argc < 3) { - fprintf(stderr, "Usage: %s fontfile size [first] [last]\n", - argv[0]); - return 1; - } - - size = atoi(argv[2]); - - if(argc == 4) { - last = atoi(argv[3]); - } else if(argc == 5) { - first = atoi(argv[3]); - last = atoi(argv[4]); - } - - if(last < first) { - i = first; - first = last; - last = i; - } - - ptr = strrchr(argv[1], '/'); // Find last slash in filename - if(ptr) ptr++; // First character of filename (path stripped) - else ptr = argv[1]; // No path; font in local dir. - - // Allocate space for font name and glyph table - if((!(fontName = malloc(strlen(ptr) + 20))) || - (!(table = (GFXglyph *)malloc((last - first + 1) * - sizeof(GFXglyph))))) { - fprintf(stderr, "Malloc error\n"); - return 1; - } - - // Derive font table names from filename. Period (filename - // extension) is truncated and replaced with the font size & bits. - strcpy(fontName, ptr); - ptr = strrchr(fontName, '.'); // Find last period (file ext) - if(!ptr) ptr = &fontName[strlen(fontName)]; // If none, append - // Insert font size and 7/8 bit. fontName was alloc'd w/extra - // space to allow this, we're not sprintfing into Forbidden Zone. - sprintf(ptr, "%dpt%db", size, (last > 127) ? 8 : 7); - // Space and punctuation chars in name replaced w/ underscores. - for(i=0; (c=fontName[i]); i++) { - if(isspace(c) || ispunct(c)) fontName[i] = '_'; - } - - // Init FreeType lib, load font - if((err = FT_Init_FreeType(&library))) { - fprintf(stderr, "FreeType init error: %d", err); - return err; - } - if((err = FT_New_Face(library, argv[1], 0, &face))) { - fprintf(stderr, "Font load error: %d", err); - FT_Done_FreeType(library); - return err; - } - - // << 6 because '26dot6' fixed-point format - FT_Set_Char_Size(face, size << 6, 0, DPI, 0); - - // Currently all symbols from 'first' to 'last' are processed. - // Fonts may contain WAY more glyphs than that, but this code - // will need to handle encoding stuff to deal with extracting - // the right symbols, and that's not done yet. - // fprintf(stderr, "%ld glyphs\n", face->num_glyphs); - - printf("const uint8_t %sBitmaps[] PROGMEM = {\n ", fontName); - - // Process glyphs and output huge bitmap data array - for(i=first, j=0; i<=last; i++, j++) { - // MONO renderer provides clean image with perfect crop - // (no wasted pixels) via bitmap struct. - if((err = FT_Load_Char(face, i, FT_LOAD_TARGET_MONO))) { - fprintf(stderr, "Error %d loading char '%c'\n", - err, i); - continue; - } - - if((err = FT_Render_Glyph(face->glyph, - FT_RENDER_MODE_MONO))) { - fprintf(stderr, "Error %d rendering char '%c'\n", - err, i); - continue; - } - - if((err = FT_Get_Glyph(face->glyph, &glyph))) { - fprintf(stderr, "Error %d getting glyph '%c'\n", - err, i); - continue; - } - - bitmap = &face->glyph->bitmap; - g = (FT_BitmapGlyphRec *)glyph; - - // Minimal font and per-glyph information is stored to - // reduce flash space requirements. Glyph bitmaps are - // fully bit-packed; no per-scanline pad, though end of - // each character may be padded to next byte boundary - // when needed. 16-bit offset means 64K max for bitmaps, - // code currently doesn't check for overflow. (Doesn't - // check that size & offsets are within bounds either for - // that matter...please convert fonts responsibly.) - table[j].bitmapOffset = bitmapOffset; - table[j].width = bitmap->width; - table[j].height = bitmap->rows; - table[j].xAdvance = face->glyph->advance.x >> 6; - table[j].xOffset = g->left; - table[j].yOffset = 1 - g->top; - - for(y=0; y < bitmap->rows; y++) { - for(x=0;x < bitmap->width; x++) { - byte = x / 8; - bit = 0x80 >> (x & 7); - enbit(bitmap->buffer[ - y * bitmap->pitch + byte] & bit); - } - } - - // Pad end of char bitmap to next byte boundary if needed - int n = (bitmap->width * bitmap->rows) & 7; - if(n) { // Pixel count not an even multiple of 8? - n = 8 - n; // # bits to next multiple - while(n--) enbit(0); - } - bitmapOffset += (bitmap->width * bitmap->rows + 7) / 8; - - FT_Done_Glyph(glyph); - } - - printf(" };\n\n"); // End bitmap array - - // Output glyph attributes table (one per character) - printf("const GFXglyph %sGlyphs[] PROGMEM = {\n", fontName); - for(i=first, j=0; i<=last; i++, j++) { - printf(" { %5d, %3d, %3d, %3d, %4d, %4d }", - table[j].bitmapOffset, - table[j].width, - table[j].height, - table[j].xAdvance, - table[j].xOffset, - table[j].yOffset); - if(i < last) { - printf(", // 0x%02X", i); - if((i >= ' ') && (i <= '~')) { - printf(" '%c'", i); - } - putchar('\n'); - } - } - printf(" }; // 0x%02X", last); - if((last >= ' ') && (last <= '~')) printf(" '%c'", last); - printf("\n\n"); - - // Output font structure - printf("const GFXfont %s PROGMEM = {\n", fontName); - printf(" (uint8_t *)%sBitmaps,\n", fontName); - printf(" (GFXglyph *)%sGlyphs,\n", fontName); - printf(" 0x%02X, 0x%02X, %ld };\n\n", - first, last, face->size->metrics.height >> 6); - printf("// Approx. %d bytes\n", - bitmapOffset + (last - first + 1) * 7 + 7); - // Size estimate is based on AVR struct and pointer sizes; - // actual size may vary. - - FT_Done_FreeType(library); - - return 0; -} - -/* ------------------------------------------------------------------------- - -Character metrics are slightly different from classic GFX & ftGFX. -In classic GFX: cursor position is the upper-left pixel of each 5x7 -character; lower extent of most glyphs (except those w/descenders) -is +6 pixels in Y direction. -W/new GFX fonts: cursor position is on baseline, where baseline is -'inclusive' (containing the bottom-most row of pixels in most symbols, -except those with descenders; ftGFX is one pixel lower). - -Cursor Y will be moved automatically when switching between classic -and new fonts. If you switch fonts, any print() calls will continue -along the same baseline. - - ...........#####.. -- yOffset - ..........######.. - ..........######.. - .........#######.. - ........#########. - * = Cursor pos. ........#########. - .......##########. - ......#####..####. - ......#####..####. - *.#.. .....#####...####. - .#.#. ....############## - #...# ...############### - #...# ...############### - ##### ..#####......##### - #...# .#####.......##### -====== #...# ====== #*###.........#### ======= Baseline - || xOffset - -glyph->xOffset and yOffset are pixel offsets, in GFX coordinate space -(+Y is down), from the cursor position to the top-left pixel of the -glyph bitmap. i.e. yOffset is typically negative, xOffset is typically -zero but a few glyphs will have other values (even negative xOffsets -sometimes, totally normal). glyph->xAdvance is the distance to move -the cursor on the X axis after drawing the corresponding symbol. - -There's also some changes with regard to 'background' color and new GFX -fonts (classic fonts unchanged). See Adafruit_GFX.cpp for explanation. -*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit-GFX-Library-master/fontconvert/fontconvert.txt Mon May 02 16:49:40 2016 +0000 @@ -0,0 +1,278 @@ +/* +TrueType to Adafruit_GFX font converter. Derived from Peter Jakobs' +Adafruit_ftGFX fork & makefont tool, and Paul Kourany's Adafruit_mfGFX. + +NOT AN ARDUINO SKETCH. This is a command-line tool for preprocessing +fonts to be used with the Adafruit_GFX Arduino library. + +For UNIX-like systems. Outputs to stdout; redirect to header file, e.g.: + ./fontconvert ~/Library/Fonts/FreeSans.ttf 18 > FreeSans18pt7b.h + +REQUIRES FREETYPE LIBRARY. www.freetype.org + +Currently this only extracts the printable 7-bit ASCII chars of a font. +Will eventually extend with some int'l chars a la ftGFX, not there yet. +Keep 7-bit fonts around as an option in that case, more compact. + +See notes at end for glyph nomenclature & other tidbits. +*/ + +#include <stdio.h> +#include <ctype.h> +#include <stdint.h> +#include <ft2build.h> +#include FT_GLYPH_H +#include "../gfxfont.h" // Adafruit_GFX font structures + +#define DPI 141 // Approximate res. of Adafruit 2.8" TFT + +// Accumulate bits for output, with periodic hexadecimal byte write +void enbit(uint8_t value) { + static uint8_t row = 0, sum = 0, bit = 0x80, firstCall = 1; + if(value) sum |= bit; // Set bit if needed + if(!(bit >>= 1)) { // Advance to next bit, end of byte reached? + if(!firstCall) { // Format output table nicely + if(++row >= 12) { // Last entry on line? + printf(",\n "); // Newline format output + row = 0; // Reset row counter + } else { // Not end of line + printf(", "); // Simple comma delim + } + } + printf("0x%02X", sum); // Write byte value + sum = 0; // Clear for next byte + bit = 0x80; // Reset bit counter + firstCall = 0; // Formatting flag + } +} + +int main(int argc, char *argv[]) { + int i, j, err, size, first=' ', last='~', + bitmapOffset = 0, x, y, byte; + char *fontName, c, *ptr; + FT_Library library; + FT_Face face; + FT_Glyph glyph; + FT_Bitmap *bitmap; + FT_BitmapGlyphRec *g; + GFXglyph *table; + uint8_t bit; + + // Parse command line. Valid syntaxes are: + // fontconvert [filename] [size] + // fontconvert [filename] [size] [last char] + // fontconvert [filename] [size] [first char] [last char] + // Unless overridden, default first and last chars are + // ' ' (space) and '~', respectively + + if(argc < 3) { + fprintf(stderr, "Usage: %s fontfile size [first] [last]\n", + argv[0]); + return 1; + } + + size = atoi(argv[2]); + + if(argc == 4) { + last = atoi(argv[3]); + } else if(argc == 5) { + first = atoi(argv[3]); + last = atoi(argv[4]); + } + + if(last < first) { + i = first; + first = last; + last = i; + } + + ptr = strrchr(argv[1], '/'); // Find last slash in filename + if(ptr) ptr++; // First character of filename (path stripped) + else ptr = argv[1]; // No path; font in local dir. + + // Allocate space for font name and glyph table + if((!(fontName = malloc(strlen(ptr) + 20))) || + (!(table = (GFXglyph *)malloc((last - first + 1) * + sizeof(GFXglyph))))) { + fprintf(stderr, "Malloc error\n"); + return 1; + } + + // Derive font table names from filename. Period (filename + // extension) is truncated and replaced with the font size & bits. + strcpy(fontName, ptr); + ptr = strrchr(fontName, '.'); // Find last period (file ext) + if(!ptr) ptr = &fontName[strlen(fontName)]; // If none, append + // Insert font size and 7/8 bit. fontName was alloc'd w/extra + // space to allow this, we're not sprintfing into Forbidden Zone. + sprintf(ptr, "%dpt%db", size, (last > 127) ? 8 : 7); + // Space and punctuation chars in name replaced w/ underscores. + for(i=0; (c=fontName[i]); i++) { + if(isspace(c) || ispunct(c)) fontName[i] = '_'; + } + + // Init FreeType lib, load font + if((err = FT_Init_FreeType(&library))) { + fprintf(stderr, "FreeType init error: %d", err); + return err; + } + if((err = FT_New_Face(library, argv[1], 0, &face))) { + fprintf(stderr, "Font load error: %d", err); + FT_Done_FreeType(library); + return err; + } + + // << 6 because '26dot6' fixed-point format + FT_Set_Char_Size(face, size << 6, 0, DPI, 0); + + // Currently all symbols from 'first' to 'last' are processed. + // Fonts may contain WAY more glyphs than that, but this code + // will need to handle encoding stuff to deal with extracting + // the right symbols, and that's not done yet. + // fprintf(stderr, "%ld glyphs\n", face->num_glyphs); + + printf("const uint8_t %sBitmaps[] PROGMEM = {\n ", fontName); + + // Process glyphs and output huge bitmap data array + for(i=first, j=0; i<=last; i++, j++) { + // MONO renderer provides clean image with perfect crop + // (no wasted pixels) via bitmap struct. + if((err = FT_Load_Char(face, i, FT_LOAD_TARGET_MONO))) { + fprintf(stderr, "Error %d loading char '%c'\n", + err, i); + continue; + } + + if((err = FT_Render_Glyph(face->glyph, + FT_RENDER_MODE_MONO))) { + fprintf(stderr, "Error %d rendering char '%c'\n", + err, i); + continue; + } + + if((err = FT_Get_Glyph(face->glyph, &glyph))) { + fprintf(stderr, "Error %d getting glyph '%c'\n", + err, i); + continue; + } + + bitmap = &face->glyph->bitmap; + g = (FT_BitmapGlyphRec *)glyph; + + // Minimal font and per-glyph information is stored to + // reduce flash space requirements. Glyph bitmaps are + // fully bit-packed; no per-scanline pad, though end of + // each character may be padded to next byte boundary + // when needed. 16-bit offset means 64K max for bitmaps, + // code currently doesn't check for overflow. (Doesn't + // check that size & offsets are within bounds either for + // that matter...please convert fonts responsibly.) + table[j].bitmapOffset = bitmapOffset; + table[j].width = bitmap->width; + table[j].height = bitmap->rows; + table[j].xAdvance = face->glyph->advance.x >> 6; + table[j].xOffset = g->left; + table[j].yOffset = 1 - g->top; + + for(y=0; y < bitmap->rows; y++) { + for(x=0;x < bitmap->width; x++) { + byte = x / 8; + bit = 0x80 >> (x & 7); + enbit(bitmap->buffer[ + y * bitmap->pitch + byte] & bit); + } + } + + // Pad end of char bitmap to next byte boundary if needed + int n = (bitmap->width * bitmap->rows) & 7; + if(n) { // Pixel count not an even multiple of 8? + n = 8 - n; // # bits to next multiple + while(n--) enbit(0); + } + bitmapOffset += (bitmap->width * bitmap->rows + 7) / 8; + + FT_Done_Glyph(glyph); + } + + printf(" };\n\n"); // End bitmap array + + // Output glyph attributes table (one per character) + printf("const GFXglyph %sGlyphs[] PROGMEM = {\n", fontName); + for(i=first, j=0; i<=last; i++, j++) { + printf(" { %5d, %3d, %3d, %3d, %4d, %4d }", + table[j].bitmapOffset, + table[j].width, + table[j].height, + table[j].xAdvance, + table[j].xOffset, + table[j].yOffset); + if(i < last) { + printf(", // 0x%02X", i); + if((i >= ' ') && (i <= '~')) { + printf(" '%c'", i); + } + putchar('\n'); + } + } + printf(" }; // 0x%02X", last); + if((last >= ' ') && (last <= '~')) printf(" '%c'", last); + printf("\n\n"); + + // Output font structure + printf("const GFXfont %s PROGMEM = {\n", fontName); + printf(" (uint8_t *)%sBitmaps,\n", fontName); + printf(" (GFXglyph *)%sGlyphs,\n", fontName); + printf(" 0x%02X, 0x%02X, %ld };\n\n", + first, last, face->size->metrics.height >> 6); + printf("// Approx. %d bytes\n", + bitmapOffset + (last - first + 1) * 7 + 7); + // Size estimate is based on AVR struct and pointer sizes; + // actual size may vary. + + FT_Done_FreeType(library); + + return 0; +} + +/* ------------------------------------------------------------------------- + +Character metrics are slightly different from classic GFX & ftGFX. +In classic GFX: cursor position is the upper-left pixel of each 5x7 +character; lower extent of most glyphs (except those w/descenders) +is +6 pixels in Y direction. +W/new GFX fonts: cursor position is on baseline, where baseline is +'inclusive' (containing the bottom-most row of pixels in most symbols, +except those with descenders; ftGFX is one pixel lower). + +Cursor Y will be moved automatically when switching between classic +and new fonts. If you switch fonts, any print() calls will continue +along the same baseline. + + ...........#####.. -- yOffset + ..........######.. + ..........######.. + .........#######.. + ........#########. + * = Cursor pos. ........#########. + .......##########. + ......#####..####. + ......#####..####. + *.#.. .....#####...####. + .#.#. ....############## + #...# ...############### + #...# ...############### + ##### ..#####......##### + #...# .#####.......##### +====== #...# ====== #*###.........#### ======= Baseline + || xOffset + +glyph->xOffset and yOffset are pixel offsets, in GFX coordinate space +(+Y is down), from the cursor position to the top-left pixel of the +glyph bitmap. i.e. yOffset is typically negative, xOffset is typically +zero but a few glyphs will have other values (even negative xOffsets +sometimes, totally normal). glyph->xAdvance is the distance to move +the cursor on the X axis after drawing the corresponding symbol. + +There's also some changes with regard to 'background' color and new GFX +fonts (classic fonts unchanged). See Adafruit_GFX.cpp for explanation. +*/