From 5c45736740e5e63439692615506078427913ea18 Mon Sep 17 00:00:00 2001 From: Neil Stockbridge Date: Tue, 20 Jul 2010 13:11:09 +1200 Subject: [PATCH] The source files are now under revision control --- Makefile | 28 ++++ fonts/un-fuzzy-4x8-font.pnm | Bin 0 -> 24629 bytes fonts/un-fuzzy-6x10-font.pnm | Bin 0 -> 46094 bytes setfont2.c | 298 +++++++++++++++++++++++++++++++++++ 4 files changed, 326 insertions(+) create mode 100644 Makefile create mode 100644 fonts/un-fuzzy-4x8-font.pnm create mode 100644 fonts/un-fuzzy-6x10-font.pnm create mode 100644 setfont2.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0daf880 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ + +PROJECT = setfont2 +STAGING_DIR = $(HOME)/nanonote/openwrt-xburst/staging_dir +ROOT_DIR = $(STAGING_DIR)/target-mipsel_uClibc-0.9.30.1 +#ROOT_DIR = "" +CC = $(STAGING_DIR)/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.30.1/usr/bin/mipsel-openwrt-linux-uclibc-gcc +STRIP = $(STAGING_DIR)/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.30.1/usr/mipsel-openwrt-linux-uclibc/bin/strip +#STRIP = strip +CFLAGS = -Wall -Os +INCLUDES = -I. -I$(ROOT_DIR)/usr/include +LIBS = -L$(ROOT_DIR)/usr/lib +PARTS = setfont2.o + +.c.o: + $(RM) $@ + $(CC) -c $(CFLAGS) $(DEFINES) $(INCLUDES) $*.c + +.SILENT: + +all: $(PROJECT) + +$(PROJECT): $(PARTS) + $(CC) -Wl,-rpath-link=$(ROOT_DIR)/usr/lib $(DEFINES) $(LIBS) -o $(PROJECT) $(PARTS) + $(STRIP) $(PROJECT) + +clean: + rm -f *.o $(PROJECT) + diff --git a/fonts/un-fuzzy-4x8-font.pnm b/fonts/un-fuzzy-4x8-font.pnm new file mode 100644 index 0000000000000000000000000000000000000000..45d23819dd911b018c1c6b39f31190f31bd58372 GIT binary patch literal 24629 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 OfkL1VC +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef char bool; +#define false 0 +#define true 1 + + +// This console magic is gratefully pinched from consolechars +int is_a_console(int fd) +{ + char arg; + + arg = 0; + return (ioctl(fd, KDGKBTYPE, &arg) == 0 + && ((arg == KB_101) || (arg == KB_84))); +} + +static int open_a_console(char *fnam) +{ + int fd; + + /* try read-only */ + fd = open(fnam, O_RDWR); + + /* if failed, try read-only */ + if (fd < 0 && errno == EACCES) + fd = open(fnam, O_RDONLY); + + /* if failed, try write-only */ + if (fd < 0 && errno == EACCES) + fd = open(fnam, O_WRONLY); + + /* if failed, fail */ + if (fd < 0) + return -1; + + /* if not a console, fail */ + if (! is_a_console(fd)) + { + close(fd); + return -1; + } + + /* success */ + return fd; +} + +int get_console_fd() +{ + int fd; + + fd = open_a_console("/dev/tty"); + if (fd >= 0) + return fd; + + fd = open_a_console("/dev/tty0"); + if (fd >= 0) + return fd; + + fd = open_a_console("/dev/console"); + if (fd >= 0) + return fd; + + for (fd = 0; fd < 3; fd++) + if (is_a_console(fd)) + return fd; + + fprintf(stderr, + "Couldnt get a file descriptor referring to the console\n"); + return -1; +} + + +typedef enum +{ + EXPECTING_FINGERPRINT, + EXPECTING_DIMENSIONS, + EXPECTING_MAXVAL, +} +ParserState; + + +typedef struct +{ + uint16_t width; + uint16_t height; + uint16_t maximum_value; + uint8_t *data; +} +Image; + + +// Loads a PNM P6 image ( 24-bit colour with binary pixel data). +// Returns 0 if the image was successfully loaded, non-zero on error. On +// error, the "error" pointer will refer to a human-readable description of +// what was wrong. +// The fields in the "image" struct may be in an undefined state on error. +// The "data" field of the image must be passed to free() when no longer +// required. +// +int load_pnm_p6( char *path_to_file, Image *image, char **error) +{ + /* EXAMPLE PNM P6 HEADER: +P6 +# CREATOR: GIMP PNM Filter Version 1.1 +128 24 +255 + + */ + FILE *f = fopen( path_to_file, "r"); + if ( NULL == f) { + *error = "Could not open file"; + return 1; // TODO - proper error code + } + + char line_store[ 80]; + ParserState state = EXPECTING_FINGERPRINT; + bool reading_header = true; + int outcome = 1; // indicating an error + + while ( reading_header) + { + char *line = fgets( line_store, sizeof(line_store), f); + + if ( NULL == line) + { + *error = "Premature end of file"; + goto tidy_up; + } + + switch ( state) + { + case EXPECTING_FINGERPRINT: + // Check that the file is in fact a P6 PNM file + if ( 0 == strcmp("P6\n", line)) { + state = EXPECTING_DIMENSIONS; + } + else { + *error = "Not a PNM P6 file"; + goto tidy_up; + } + break; + case EXPECTING_DIMENSIONS: + // If this line does NOT contain a comment.. + if ( line[ 0] != '#') + { + // Try to get the dimensions of the image from the line + int count = sscanf( line, "%hu %hu\n", &image->width, &image->height); + if ( count != 2) { + *error = "Bad dimensions line"; + goto tidy_up; + } + state = EXPECTING_MAXVAL; + } + break; + case EXPECTING_MAXVAL: + { + // Try to get the maximum pixel value in the image from the line + int count = sscanf( line, "%hu\n", &image->maximum_value); + if ( count != 1) { + *error = "Bad maxval line"; + goto tidy_up; + } + // The binary data follows the Depth line + reading_header = false; + } + } + } + + image->data = malloc( 3 * image->width * image->height); + size_t rows_read = fread( image->data, 3 * image->width, image->height, f); + if ( rows_read != image->height) + { + *error = "Some data is missing"; + goto tidy_up; + } + + // Indicate that no error occurred + outcome = 0; + + tidy_up: + fclose( f); + + return outcome; +} + + +int main( int argc, char **argv) +{ + if ( argc != 2) + { + fprintf( stderr, "Use: %s path-to-glyph-sheet.pnm\n", argv[0]); + exit( 1); + } + + // Load the glyph sheet from the PNM file + Image image; + char *error; + int outcome = load_pnm_p6( argv[1], &image, &error); + if ( outcome != 0) + { + fprintf( stderr, "Could not load glyph sheet: %s\n", error); + exit( 1); + } + + bool should_emit_data = false; + + // The glyph sheet is expected to have 8 rows of 32 glyphs. The image + // dimensions will be used to determine the glyph cell dimensions. + uint8_t pixels_across_glyph = image.width / 32; + uint8_t pixels_down_glyph = image.height / 8; + uint8_t bytes_across_glyph = 4 * pixels_across_glyph; + uint8_t bytes_per_glyph = bytes_across_glyph * pixels_down_glyph; + + uint16_t charcount = 256; + unsigned char data[ bytes_per_glyph * charcount]; + + // Initialize the kernel glyph sheet so that unused pixels are empty + memset( data, 0x00, sizeof(data)); + + int ch, y, x; + for ( ch = 0; ch < 256; ++ch) + { + // Work out the row number on the glyph sheet of the glyph for "ch" + // There are 8 rows of 32 glyphs on the image + uint8_t glyph_sheet_row = ch / 32; + uint8_t glyph_sheet_column = ch % 32; + uint8_t top_edge_of_glyph = pixels_down_glyph * glyph_sheet_row; + uint8_t left_edge_of_glyph = pixels_across_glyph * glyph_sheet_column; + + if ( should_emit_data) { + printf("%c\n", ch); + } + + for ( y = 0; y < pixels_down_glyph; ++ y) + { + uint8_t *file_glyph_row = &image.data[ 3 * ( image.width * ( top_edge_of_glyph + y) + left_edge_of_glyph)]; + uint8_t *kernel_glyph_row = &data[ bytes_per_glyph * ch + bytes_across_glyph * y]; + if ( bytes_per_glyph * ch + bytes_across_glyph * y + bytes_across_glyph <= sizeof(data)) + { + // Copy the row of pixels from the file sheet to the kernel sheet + for ( x = 0; x < pixels_across_glyph; ++ x) + { + kernel_glyph_row[ 4*x + 0] = file_glyph_row[ 3*x + 2]; + kernel_glyph_row[ 4*x + 1] = file_glyph_row[ 3*x + 1]; + kernel_glyph_row[ 4*x + 2] = file_glyph_row[ 3*x + 0]; + if ( should_emit_data) { + uint8_t *row = kernel_glyph_row + 4*x; + printf("%02hx,%02hx,%02hx,%02hx ", row[0], row[1], row[2], row[3]); + } + } + if ( should_emit_data) { + printf("\n"); + } + } + else { + fprintf( stderr, "Shit\n"); + goto tidy_up; + } + } + } + + // Leave a fingerprint of this non-standard font so the kernel can recognise + // it as such + *(uint32_t*)data = 0x6a127efd; + + struct console_font_op request = { op: KD_FONT_OP_SET, + width: pixels_across_glyph, + height: pixels_down_glyph, + charcount: 256, + data: data, + }; + + if ( ioctl( get_console_fd(), KDFONTOP, &request)) { + perror("Bugger"); + } + + tidy_up: + free( image.data); + + return 0; +} +