diff options
Diffstat (limited to 'components/fasani__adafruit_gfx/fontconvert')
4 files changed, 416 insertions, 0 deletions
diff --git a/components/fasani__adafruit_gfx/fontconvert/Makefile b/components/fasani__adafruit_gfx/fontconvert/Makefile new file mode 100644 index 0000000..47f5a0e --- /dev/null +++ b/components/fasani__adafruit_gfx/fontconvert/Makefile @@ -0,0 +1,12 @@ +all: fontconvert + +CC = gcc +CFLAGS = -Wall -I/usr/local/include/freetype2 -I/usr/include/freetype2 -I/usr/include +LIBS = -lfreetype + +fontconvert: fontconvert.c + $(CC) $(CFLAGS) $< $(LIBS) -o $@ + strip $@ + +clean: + rm -f fontconvert diff --git a/components/fasani__adafruit_gfx/fontconvert/fontconvert.c b/components/fasani__adafruit_gfx/fontconvert/fontconvert.c new file mode 100644 index 0000000..c6d6498 --- /dev/null +++ b/components/fasani__adafruit_gfx/fontconvert/fontconvert.c @@ -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. +*/ diff --git a/components/fasani__adafruit_gfx/fontconvert/fontconvert_win.md b/components/fasani__adafruit_gfx/fontconvert/fontconvert_win.md new file mode 100644 index 0000000..1932841 --- /dev/null +++ b/components/fasani__adafruit_gfx/fontconvert/fontconvert_win.md @@ -0,0 +1,88 @@ +### A short guide to use fontconvert.c to create your own fonts using MinGW.
+
+#### STEP 1: INSTALL MinGW
+
+Install MinGW (Minimalist GNU for Windows) from [MinGW.org](http://www.mingw.org/).
+Please read carefully the instructions found on [Getting started page](http://www.mingw.org/wiki/Getting_Started).
+I suggest installing with the "Graphical User Interface Installer".
+To complete your initial installation you should further install some "packages".
+For our purpose you should only install the "Basic Setup" packages.
+To do that:
+
+1. Open the MinGW Installation Manager
+2. From the left panel click "Basic Setup".
+3. On the right panel choose "mingw32-base", "mingw-gcc-g++", "mingw-gcc-objc" and "msys-base"
+and click "Mark for installation"
+4. From the Menu click "Installation" and then "Apply changes". In the pop-up window select "Apply".
+
+
+#### STEP 2: INSTALL Freetype Library
+
+To read about the freetype project visit [freetype.org](https://www.freetype.org/).
+To Download the latest version of freetype go to [download page](http://download.savannah.gnu.org/releases/freetype/)
+and choose "freetype-2.7.tar.gz" file (or a newer version if available).
+To avoid long cd commands later in the command prompt, I suggest you unzip the file in the C:\ directory.
+(I also renamed the folder to "ft27")
+Before you build the library it's good to read these articles:
+* [Using MSYS with MinGW](http://www.mingw.org/wiki/MSYS)
+* [Installation and Use of Supplementary Libraries with MinGW](http://www.mingw.org/wiki/LibraryPathHOWTO)
+* [Include Path](http://www.mingw.org/wiki/IncludePathHOWTO)
+
+Inside the unzipped folder there is another folder named "docs". Open it and read the INSTALL.UNIX (using notepad).
+Pay attention to paragraph 3 (Build and Install the Library). So, let's begin the installation.
+To give the appropriate commands we will use the MSYS command prompt (not cmd.exe of windows) which is UNIX like.
+Follow the path C:\MinGW\msys\1.0 and double click "msys.bat". The command prompt environment appears.
+Enter "ft27" directory using the cd commands:
+```
+cd /c
+cd ft27
+```
+
+and then type one by one the commands:
+```
+./configure --prefix=/mingw
+make
+make install
+```
+Once you're finished, go inside "C:\MinGW\include" and there should be a new folder named "freetype2".
+That, hopefully, means that you have installed the library correctly !!
+
+#### STEP 3: Build fontconvert.c
+
+Before proceeding I suggest you make a copy of Adafruit_GFX_library folder in C:\ directory.
+Then, inside "fontconvert" folder open the "makefile" with an editor ( I used notepad++).
+Change the commands so in the end the program looks like :
+```
+all: fontconvert
+
+CC = gcc
+CFLAGS = -Wall -I c:/mingw/include/freetype2
+LIBS = -lfreetype
+
+fontconvert: fontconvert.c
+ $(CC) $(CFLAGS) $< $(LIBS) -o $@
+
+clean:
+ rm -f fontconvert
+```
+Go back in the command prompt and with a cd command enter the fontconvert directory.
+```
+cd /c/adafruit_gfx_library\fontconvert
+```
+Give the command:
+```
+make
+```
+This command will, eventually, create a "fontconvert.exe" file inside fontconvert directory.
+
+#### STEP 4: Create your own font header files
+
+Now that you have an executable file, you can use it to create your own fonts to work with Adafruit GFX lib.
+So, if we suppose that you already have a .ttf file with your favorite fonts, jump to the command prompt and type:
+```
+./fontconvert yourfonts.ttf 9 > yourfonts9pt7b.h
+```
+You can read more details at: [learn.adafruit](https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts).
+
+Taraaaaaammm !! you've just created your new font header file. Put it inside the "Fonts" folder, grab a cup of coffee
+and start playing with your Arduino (or whatever else ....)+ display module project.
diff --git a/components/fasani__adafruit_gfx/fontconvert/makefonts.sh b/components/fasani__adafruit_gfx/fontconvert/makefonts.sh new file mode 100755 index 0000000..35f07ea --- /dev/null +++ b/components/fasani__adafruit_gfx/fontconvert/makefonts.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Ugly little Bash script, generates a set of .h files for GFX using +# GNU FreeFont sources. There are three fonts: 'Mono' (Courier-like), +# 'Sans' (Helvetica-like) and 'Serif' (Times-like); four styles: regular, +# bold, oblique or italic, and bold+oblique or bold+italic; and four +# sizes: 9, 12, 18 and 24 point. No real error checking or anything, +# this just powers through all the combinations, calling the fontconvert +# utility and redirecting the output to a .h file for each combo. + +# Adafruit_GFX repository does not include the source outline fonts +# (huge zipfile, different license) but they're easily acquired: +# http://savannah.gnu.org/projects/freefont/ + +convert=./fontconvert +inpath=~/Desktop/freefont/ +outpath=../Fonts/ +fonts=(FreeMono FreeSans FreeSerif) +styles=("" Bold Italic BoldItalic Oblique BoldOblique) +sizes=(9 12 18 24) + +for f in ${fonts[*]} +do + for index in ${!styles[*]} + do + st=${styles[$index]} + for si in ${sizes[*]} + do + infile=$inpath$f$st".ttf" + if [ -f $infile ] # Does source combination exist? + then + outfile=$outpath$f$st$si"pt7b.h" +# printf "%s %s %s > %s\n" $convert $infile $si $outfile + $convert $infile $si > $outfile + fi + done + done +done |
