Made MD* libraries (Parola, MAX72XX) project specific, to be able to use the newest software version from github.

This commit is contained in:
2019-02-01 15:21:58 +01:00
parent fe9f25c856
commit c7547144d2
761 changed files with 108577 additions and 2 deletions

View File

@@ -0,0 +1,280 @@
// Font 2 Text for MD_MAX72xx library
//
// Quick and not very robust code to create a font defintion text file
// from an existing font data table. This is considered a one-off task
// followed by some manual editing of the file.
// The file is expected to be in the similar format to the output from
// txt2font. Specifically,
// - it is expected that each character is on one data line in order to
// recognise specific parts, like comments.
// - it expects all the ascii codes to be present (ie, it does not respect
// the version information at the start of the table)
//
// The shared header file means that some elements in this
// code are reversed (eg, the IN file extension is used as the OUT file
// extension). Each font element is output as it is completed, without
// buffering the while ASCII set.
//
#include "txt2font.h"
// Global data ---------------
Global_t G;
ASCIIDef_t font = { 0 };
// Code ----------------------
void usage(void)
{
printf("\nusage: font2txt <root_name>\n");
printf("\n\ninput file <root_name>.h");
printf("\noutput file <root_name>.txt");
printf("\n");
return;
}
int cmdLine(int argc, char *argv[])
// process the command line parameter
{
if (argc != 2)
return(1);
strcpy(G.fileRoot, argv[1]);
return(0);
}
int initialise(void)
// one time initiualisation code
{
char szFile[FILE_NAME_SIZE];
// we have no font definition
font.comment[0] = NUL;
font.size = 0;
font.buf = malloc(100*sizeof(font.buf[0])); // pick a big number...
// open the file for reading
strcpy(szFile, G.fileRoot);
strcat(szFile, OUT_FILE_EXT);
if ((G.fpIn = fopen(szFile, "r")) == NULL)
{
printf("\nCannot open input ""%s\n""", szFile);
return(2);
}
// open the file for writing
strcpy(szFile, G.fileRoot);
strcat(szFile, IN_FILE_EXT);
if ((G.fpOut = fopen(szFile, "w")) == NULL)
{
printf("\nCannot open output ""%s\n""", szFile);
return(3);
}
// other stuff
G.name[0] = NUL;
G.doubleHeight = 0;
G.bufSize = SINGLE_HEIGHT;
G.fixedWidth = 0;
return(0);
}
void trimBuffer(char *buf)
// trim the buffer specified of all trailing white space
{
int i = strlen(buf)-1;
while (i > 0 && isspace(buf[i]))
buf[i--] = NUL;
return;
}
void padBuffer(char *buf, unsigned int len)
// pad the supplied buffer with spaces up to the length specified
{
if (strlen(buf) < len)
{
for (unsigned int j=strlen(buf); j<len; j++)
buf[j] = SPACE;
}
buf[len] = NUL;
return;
}
unsigned int normaliseBuffers(void)
// normalise all the input buffers to the same size
{
unsigned int max = 0;
if (G.fixedWidth == 0)
{
for (unsigned int i=0; i<G.bufSize; i++)
max = max < strlen(G.buf[i]) ? max = strlen(G.buf[i]) : max;
}
else
max = G.fixedWidth;
// now make them all the same size
for (unsigned int i=0; i<G.bufSize; i++)
{
padBuffer(G.buf[i], max);
}
return(max);
}
char *getToken(char *buf)
// isolate the first token in the buffer and return a pointer to the next non white space after the token
{
while (isspace(*buf) || ispunct(*buf))
buf++;
while (!isspace(*buf) && !ispunct(*buf))
buf++;
*buf++ = NUL;
while (isspace(*buf) || ispunct(*buf))
buf++;
return(buf);
}
void saveOutputHeader(void)
// save the current definition as a font definition header file
{
fprintf(G.fpOut, "%c%s %s\n", DOT, CMD_NAME, G.fileRoot);
fprintf(G.fpOut, "%c%s %d\n", DOT, CMD_HEIGHT, (G.doubleHeight ? 2: 1));
fprintf(G.fpOut, "%c%s %d\n", DOT, CMD_WIDTH, G.fixedWidth);
fprintf(G.fpOut, "%c%s %d %s\n", DOT, CMD_FONTHIGH, G.fontHeight, "<- THIS NEEDS EDITING");
return;
}
void saveOutputFooter(void)
// save the current definition as a font definition header file
{
fprintf(G.fpOut, "%c%s\n", DOT, CMD_END);
return;
}
void saveOutputChar(void)
// Save a single character definition
{
fprintf(G.fpOut, "%c%s %d\n", DOT, CMD_CHAR, G.curCode);
fprintf(G.fpOut, "%c%s %s\n", DOT, CMD_NOTE, font.comment);
if (G.bufSize != 0)
{
for (unsigned int i=0; i<G.bufSize; i++)
{
trimBuffer(G.buf[i]);
fprintf(G.fpOut, "%s\n", G.buf[i]);
}
}
else // need at least one line
fprintf(G.fpOut, "\n");
return;
}
void createFontData(char *cp)
// the font defintions strings are column data, so each byte will be a 'vertical'
// stripe of the input buffers. Format is the size followed by size bytes of column data,
// separated by commas. The comment is found after the data in a '//' comment and following
// the first '-'.
{
char *cpNext;
cpNext = getToken(cp);
font.size = atoi(cp);
cp = cpNext;
// get all the data from the input into the font defintion
for (unsigned int i=0; i<font.size; i++)
{
// get the data
cpNext = getToken(cp);
font.buf[i] = atoi(cp);
cp = cpNext;
}
// unpack the column data into the text strings
// create each input string [j] in turn from the column definition [i] for the char
for (unsigned int i=0; i<SINGLE_HEIGHT; i++)
{
for (unsigned int j=0; j<font.size; j++)
G.buf[i][j] = (font.buf[j] & (1<<i)) ? STAR : SPACE;
G.buf[i][font.size] = NUL; // terminate the string
}
// save the comment - first search up to after the first '-'
while ((*cp != '-') && (*cp != NUL))
cp++;
if (cp != NUL) cp++;
strcpy(font.comment, cp);
return;
}
void processInput(void)
// read the input file and process line by line
{
char c, inLine[INPUT_BUFFER_SIZE];
// skip to the opening brace then skip end of line
do
c = getc(G.fpIn);
while ((c != EOF) && (c != '{'));
do
c = getc(G.fpIn);
while ((c == '\n') || (c == '\r'));
// now read each line in turn
while (!feof(G.fpIn) && (G.curCode < ASCII_SIZE))
{
fgets(inLine, sizeof(inLine), G.fpIn);
// if we have a blank line, get another one
trimBuffer(inLine);
if (strlen(inLine) == 0) continue;
// process the buffers into a font definition and write out what we have created
createFontData(inLine);
saveOutputChar();
// reset the font and character buffers, increment current ASCII code
for (unsigned int i=0; i<G.bufSize; i++)
G.buf[i][0] = NUL;
font.size = 0;
G.curCode++;
}
return;
}
int main(int argc, char *argv[])
{
int ret;
if (cmdLine(argc, argv))
{
usage();
return(1);
}
if ((ret = initialise()) != 0)
return(ret);
saveOutputHeader();
processInput();
saveOutputFooter();
// close files and exit
fclose(G.fpIn);
fclose(G.fpOut);
return(0);
}

View File

@@ -0,0 +1,71 @@
/* Text 2 Font for MD_MAX72xx library
Quick and not very robust code to create a font definition data table for the
MD_MAX72xx library from a text file representation. The text file has '.' commands
to direct how the definition is structured.
This is a console application written in standard C.
Original target is Win32, but no OS dependencies, so should be portable to other OS.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#pragma once
#define NAME_SIZE 50
#define FILE_NAME_SIZE 200 // may include path
#define FONT_NAME_SIZE 50
#define COMMENT_SIZE 40
#define ASCII_SIZE 256
#define INPUT_BUFFER_SIZE 200
#define SINGLE_HEIGHT 8
#define DOUBLE_HEIGHT_OFFSET (ASCII_SIZE/2) // ASCII code offset
#define IN_FILE_EXT ".txt"
#define OUT_FILE_EXT ".h"
#define SPACE ' '
#define STAR '*'
#define NUL '\0'
#define DOT '.'
#define CMD_NAME "NAME"
#define CMD_FONTHIGH "FONT_HEIGHT"
#define CMD_HEIGHT "HEIGHT"
#define CMD_WIDTH "WIDTH"
#define CMD_CHAR "CHAR"
#define CMD_NOTE "NOTE"
#define CMD_END "END"
// Data types ----------------
typedef struct
{
// file handling
FILE *fpIn;
FILE *fpOut;
char fileRoot[FILE_NAME_SIZE];
// font definition header
char name[FONT_NAME_SIZE];
unsigned int doubleHeight; // 0 or 1
unsigned int fixedWidth; // 0 for variable, width otherwise
unsigned int fontHeight; // height in pixels, default to 8
// input buffers and tracking
unsigned int curCode; // the current ASCII character being processed
unsigned int curBuf; // the current buffer we are up to
unsigned int bufSize; // the number of buffers used
char buf[SINGLE_HEIGHT*2][INPUT_BUFFER_SIZE];
} Global_t, *pGlobal_t;
typedef struct
{
char comment[COMMENT_SIZE]; // comment for this character
unsigned int size; // number of valid
unsigned int *buf; // size bytes allocated from memory
} ASCIIDef_t, *pASCIIDef_t;

View File

@@ -0,0 +1,376 @@
// Text 2 Font for MD_MAX72xx library
//
// Quick and not very robust code to create a font definition data table for the
// MD_MAX72xx library from a text file representation. The text file has '.' commands
// to direct how the definition is structured.
//
#include "txt2font.h"
//#define DEBUG
#define DECIMAL_DATA 0 // decimal or hex data selection in font tables
// Global data ---------------
Global_t G;
ASCIIDef_t font[ASCII_SIZE] = { 0 };
// Code ----------------------
void usage(void)
{
printf("\nusage: txt2font <root_name>\n");
printf("\n\ninput file <root_name>.txt");
printf("\noutput file <root_name>.h");
printf("\n");
return;
}
int cmdLine(int argc, char *argv[])
// process the command line parameter
{
if (argc != 2)
return(1);
strcpy(G.fileRoot, argv[1]);
return(0);
}
int initialise(void)
// one time initialisation code
{
char szFile[FILE_NAME_SIZE];
// we have no font definition
for (int i=0; i<ASCII_SIZE; i++)
{
font[i].comment[0] = NUL;
font[i].size = 0;
font[i].buf = NULL;
}
// open the file for reading
strcpy(szFile, G.fileRoot);
strcat(szFile, IN_FILE_EXT);
if ((G.fpIn = fopen(szFile, "r")) == NULL)
{
printf("\nCannot open input ""%s\n""", szFile);
return(2);
}
// open the file for writing
strcpy(szFile, G.fileRoot);
strcat(szFile, OUT_FILE_EXT);
if ((G.fpOut = fopen(szFile, "w")) == NULL)
{
printf("\nCannot open output ""%s\n""", szFile);
return(3);
}
// other stuff
G.name[0] = NUL;
G.doubleHeight = 0;
G.bufSize = SINGLE_HEIGHT;
G.fixedWidth = 0;
G.fontHeight = 8;
return(0);
}
void trimBuffer(char *buf)
// trim the buffer specified of all trailing white space
{
int i = strlen(buf)-1;
while (i > 0 && isspace(buf[i]))
buf[i--] = NUL;
return;
}
void padBuffer(char *buf, unsigned int len)
// pad the supplied buffer with spaces up to the length specified
{
if (strlen(buf) < len)
{
for (unsigned int j=strlen(buf); j<len; j++)
buf[j] = SPACE;
}
buf[len] = NUL;
return;
}
unsigned int normaliseBuffers(void)
// normalize all the input buffers to the same size
{
unsigned int max = 0;
if (G.fixedWidth == 0)
{
for (unsigned int i=0; i<G.bufSize; i++)
max = max < strlen(G.buf[i]) ? max = strlen(G.buf[i]) : max;
}
else
max = G.fixedWidth;
// now make them all the same size
for (unsigned int i=0; i<G.bufSize; i++)
{
padBuffer(G.buf[i], max);
}
return(max);
}
char *getToken(char *buf)
// isolate the first token in the buffer and return a pointer to the next non white space after the token
{
while (!isspace(*buf))
buf++;
*buf++ = NUL;
while (isspace(*buf))
buf++;
return(buf);
}
void createFontChar(void)
// the font definition strings are created as columns, so each byte will be a 'vertical'
// stripe of the input buffers.
{
font[G.curCode].size = normaliseBuffers(); // make everything the same length; this is the width of the character
// allocate memory for the font data
if (font[G.curCode].buf != NULL)
free(font[G.curCode].buf);
font[G.curCode].buf = malloc(font[G.curCode].size * sizeof(*font[0].buf));
// if double height, check the upper buffers and also copy the font data across
if (G.doubleHeight)
{
if (font[G.curCode+DOUBLE_HEIGHT_OFFSET].buf != NULL)
free(font[G.curCode+DOUBLE_HEIGHT_OFFSET].buf);
font[G.curCode+DOUBLE_HEIGHT_OFFSET].buf = malloc(font[G.curCode].size * sizeof(*font[0].buf));
font[G.curCode+DOUBLE_HEIGHT_OFFSET].size = font[G.curCode].size;
strcpy(font[G.curCode+DOUBLE_HEIGHT_OFFSET].comment, font[G.curCode].comment);
}
// process the input strings in parallel [j] to create the column definition [i] for the first character
for (unsigned int i=0; i<font[G.curCode].size; i++)
{
unsigned int colL, colH;
if (G.doubleHeight) // if we are double height, write lower and upper halves separately
{
colL = colH = 0;
// high half of character stored in upper ASCII value, but in low buffers
// low half of character stored in lower ASCII value, but in high buffers
for (unsigned int j=0; j<SINGLE_HEIGHT; j++)
{
colH |= (G.buf[j][i] == SPACE) ? 0 : (1 << j);
colL |= (G.buf[j+SINGLE_HEIGHT][i] == SPACE) ? 0 : (1 << j);
}
font[G.curCode+DOUBLE_HEIGHT_OFFSET].buf[i] = colH;
font[G.curCode].buf[i] = colL;
}
else
{
colL = 0;
for (unsigned int j=0; j<SINGLE_HEIGHT; j++)
colL |= (G.buf[j][i] == SPACE) ? 0 : (1 << j);
// save the column data
font[G.curCode].buf[i] = colL;
}
}
return;
}
void readInput(void)
// read the input file and process line by line
{
char c, *cp, inLine[INPUT_BUFFER_SIZE];
cp = inLine;
while ((c = getc(G.fpIn)) != EOF)
{
if (c != '\n' && c != '\r') // not end of line
{
*cp++ = c;
continue;
}
// we are at end of line, process the line
*cp = NUL;
trimBuffer(inLine);
if (inLine[0] != DOT) // not a command? must be a chr definition line
{
if (G.curBuf < (SINGLE_HEIGHT*2))
{
#ifdef DEBUG
printf("\nC%02x L%d\t%s", G.curCode, G.curBuf, inLine);
#endif
strcpy(G.buf[G.curBuf++], inLine); // save the buffer
}
}
else
{
cp = getToken(&inLine[1]);
#ifdef DEBUG
printf("\nToken: '%s' - '%s'", inLine, cp);
#endif
if (strcmp(&inLine[1], CMD_NAME) == 0)
{
strcpy(G.name, cp);
#ifdef DEBUG
printf("\tfont name: '%s'", G.name);
#endif
}
else if (strcmp(&inLine[1], CMD_FONTHIGH) == 0)
{
G.fontHeight = abs(atoi(cp));
#ifdef DEBUG
printf("\tfont height: %d", G.fontHeight);
#endif
}
else if (strcmp(&inLine[1], CMD_HEIGHT) == 0)
{
G.doubleHeight = (*cp=='1' ? 0 : 1);
G.bufSize = (*cp=='1' ? SINGLE_HEIGHT : SINGLE_HEIGHT*2);
#ifdef DEBUG
printf("\tdouble height: %d", G.doubleHeight);
#endif
}
else if (strcmp(&inLine[1], CMD_WIDTH) == 0)
{
G.fixedWidth = abs(atoi(cp));
#ifdef DEBUG
printf("\twidth: %d", G.fixedWidth);
#endif
}
else if ((strcmp(&inLine[1], CMD_CHAR) == 0) ||
(strcmp(&inLine[1], CMD_END) == 0))
{
#ifdef DEBUG
printf("\tend char %02x", G.curCode);
#endif
if (G.curBuf != 0) // we have buffers
{
// process the buffers into a font definition
createFontChar();
// reset the character buffers
for (unsigned int i=0; i<G.bufSize; i++)
G.buf[i][0] = NUL;
}
// set up the new character if not at the end
if (strcmp(&inLine[1], CMD_END) != 0)
{
G.curBuf = 0;
G.curCode = atoi(cp);
#ifdef DEBUG
printf("\t set up %02x", G.curCode);
#endif
if (G.curCode >= (G.doubleHeight ? ASCII_SIZE/2 : ASCII_SIZE))
{
G.curCode = 0;
#ifdef DEBUG
printf("\t - boundary check fail");
#endif
}
font[G.curCode].comment[0] = NUL;
font[G.curCode].size = 0;
}
#ifdef DEBUG
else
printf("\tend of definition");
#endif
}
else if (strcmp(&inLine[1], CMD_NOTE) == 0)
{
strcpy(font[G.curCode].comment, cp);
#ifdef DEBUG
printf("\tnote '%s' for char %02x", font[G.curCode].comment, G.curCode);
#endif
}
}
// reset for next line
cp = inLine;
memset(inLine, NUL, sizeof(inLine));
}
return;
}
void saveOutput(void)
// save the current definition as a font definition header file
{
unsigned int minAscii = 0, maxAscii = 0;
// first parse the font table to work out the min and max ASCII values
for (int i=0; i<ASCII_SIZE; i++)
if (font[i].buf != NULL) maxAscii = i;
for (int i=maxAscii; i>=0; i--)
if (font[i].buf != NULL) minAscii = i;
fprintf(G.fpOut, "// Autogenerated font - '%s'\n", G.name);
fprintf(G.fpOut, "// %s height, ", (G.doubleHeight ? "Double" : "Single"));
if (G.fixedWidth == 0)
fprintf(G.fpOut, "Variable spaced");
else
fprintf(G.fpOut, "Fixed width (%d)", G.fixedWidth);
fprintf(G.fpOut, "\n\n");
fprintf(G.fpOut, "#pragma once\n\n");
fprintf(G.fpOut, "const uint8_t PROGMEM _%s[] = \n{\n", (G.name[0] == NUL) ? "font" : G.name);
fprintf(G.fpOut, "'F', 1, %d, %d, %d,\n", minAscii, maxAscii, G.fontHeight);
for (int i=minAscii; i<=maxAscii; i++)
{
fprintf(G.fpOut, "\t%d,", font[i].size);
if (font[i].buf != NULL)
{
for (unsigned int j=0; j<font[i].size; j++)
fprintf(G.fpOut, (DECIMAL_DATA ? "%d," : "0x%02x,"), font[i].buf[j]);
}
fprintf(G.fpOut, "\t// %d", i);
if (font[i].comment[0] != NUL)
fprintf(G.fpOut," - %s", font[i].comment);
fprintf(G.fpOut, "\n");
}
fprintf(G.fpOut, "}\n\n");
}
int main(int argc, char *argv[])
{
int ret;
if (cmdLine(argc, argv))
{
usage();
return(1);
}
if ((ret = initialise()) != 0)
return(ret);
// read the input file
readInput();
// write the output file
saveOutput();
// close files and exit
fclose(G.fpIn);
fclose(G.fpOut);
return(0);
}

View File

@@ -0,0 +1,71 @@
/* Text 2 Font for MD_MAX72xx library
Quick and not very robust code to create a font definition data table for the
MD_MAX72xx library from a text file representation. The text file has '.' commands
to direct how the definition is structured.
This is a console application written in standard C.
Original target is Win32, but no OS dependencies, so should be portable to other OS.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#pragma once
#define NAME_SIZE 50
#define FILE_NAME_SIZE 200 // may include path
#define FONT_NAME_SIZE 50
#define COMMENT_SIZE 40
#define ASCII_SIZE 256
#define INPUT_BUFFER_SIZE 200
#define SINGLE_HEIGHT 8
#define DOUBLE_HEIGHT_OFFSET (ASCII_SIZE/2) // ASCII code offset
#define IN_FILE_EXT ".txt"
#define OUT_FILE_EXT ".h"
#define SPACE ' '
#define STAR '*'
#define NUL '\0'
#define DOT '.'
#define CMD_NAME "NAME"
#define CMD_FONTHIGH "FONT_HEIGHT"
#define CMD_HEIGHT "HEIGHT"
#define CMD_WIDTH "WIDTH"
#define CMD_CHAR "CHAR"
#define CMD_NOTE "NOTE"
#define CMD_END "END"
// Data types ----------------
typedef struct
{
// file handling
FILE *fpIn;
FILE *fpOut;
char fileRoot[FILE_NAME_SIZE];
// font definition header
char name[FONT_NAME_SIZE];
unsigned int doubleHeight; // 0 or 1
unsigned int fixedWidth; // 0 for variable, width otherwise
unsigned int fontHeight; // height in pixels, default to 8
// input buffers and tracking
unsigned int curCode; // the current ASCII character being processed
unsigned int curBuf; // the current buffer we are up to
unsigned int bufSize; // the number of buffers used
char buf[SINGLE_HEIGHT*2][INPUT_BUFFER_SIZE];
} Global_t, *pGlobal_t;
typedef struct
{
char comment[COMMENT_SIZE]; // comment for this character
unsigned int size; // number of valid
unsigned int *buf; // size bytes allocated from memory
} ASCIIDef_t, *pASCIIDef_t;