initial commit, font-tool started
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 8 Aug 2023 03:16:16 +0000 (06:16 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 8 Aug 2023 03:16:16 +0000 (06:16 +0300)
.gitignore [new file with mode: 0644]
menu/Makefile [new file with mode: 0644]
menu/tools/fontconv/Makefile [new file with mode: 0644]
menu/tools/fontconv/fontconv.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e45a17c
--- /dev/null
@@ -0,0 +1,5 @@
+*.o
+*.swp
+*.d
+*.pgm
+*.metrics
diff --git a/menu/Makefile b/menu/Makefile
new file mode 100644 (file)
index 0000000..bb74e85
--- /dev/null
@@ -0,0 +1,53 @@
+src = $(wildcard src/*.c) $(wildcard src/dos/*.c)
+asmsrc = $(wildcard src/*.asm) $(wildcard src/dos/*.asm)
+obj = $(src:.c=.o)
+dep = $(src:.c=.d)
+bin = menu.exe
+
+ifeq ($(findstring COMMAND.COM, $(SHELL)), COMMAND.COM)
+       hostsys = dos
+else
+       hostsys = unix
+       TOOLPREFIX = i586-pc-msdosdjgpp-
+endif
+
+#opt = -O3
+dbg = -g
+warn = -pedantic -Wall
+
+CC = $(TOOLPREFIX)gcc
+AR = $(TOOLPREFIX)ar
+CFLAGS = $(warn) $(dbg) $(opt) $(inc) $(def) -MMD
+
+$(bin): $(obj)
+       $(CC) -o $@ -Wl,-Map=menu.map $(obj) $(LDFLAGS)
+
+-include $(dep)
+
+%.cof: %.c
+       $(CC) $(CFLAGS) -o $@ -c $<
+
+%.cof: %.asm
+       nasm -f coff -o $@ $<
+
+
+.PHONY: clean
+.PHONY: cleandep
+
+ifeq ($(hostsys), dos)
+clean:
+       del src\*.cof
+       del src\dos\*.cof
+       del $(bin)
+       del menu.map
+
+cleandep:
+       del src\*.dep
+       del src\dos\*.dep
+else
+clean:
+       rm -f $(obj) $(bin)
+
+cleandep:
+       rm -f $(dep)
+endif
diff --git a/menu/tools/fontconv/Makefile b/menu/tools/fontconv/Makefile
new file mode 100644 (file)
index 0000000..369e99f
--- /dev/null
@@ -0,0 +1,12 @@
+obj = fontconv.o
+bin = fontconv
+
+CFLAGS = -pedantic -Wall -g
+LDFLAGS = -lGL -lglut -lm
+
+$(bin): $(obj)
+       $(CC) -o $@ $(obj) $(LDFLAGS)
+
+.PHONY: clean
+clean:
+       rm -f $(obj) $(bin)
diff --git a/menu/tools/fontconv/fontconv.c b/menu/tools/fontconv/fontconv.c
new file mode 100644 (file)
index 0000000..4ed71e2
--- /dev/null
@@ -0,0 +1,234 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <GL/glut.h>
+
+struct glyph {
+       int code;
+       int x, y;
+       int width, height;
+};
+
+void display(void);
+void reshape(int x, int y);
+void keyboard(unsigned char key, int x, int y);
+
+int save_image(const char *fname, int width, int height, unsigned char *img);
+int save_metrics(const char *fname, struct glyph *glyphs, int num_glyphs);
+
+int win_width, win_height;
+int serif, fontsz = 10;
+void *font;
+
+struct glyph glyphs[128];
+int num_glyphs;
+int baseline;
+unsigned char *glyphmap;
+
+static const char *usage_fmt = "Usage %s [options]\n"
+       " -sans: sans-serif font\n"
+       " -serif: serif font\n"
+       " -size <n>: font size\n"
+       " -help: print usage and exit\n\n";
+
+int main(int argc, char **argv)
+{
+       int i;
+
+       glutInitWindowSize(256, 32);
+       glutInit(&argc, argv);
+
+       for(i=1; i<argc; i++) {
+               if(argv[i][0] == '-') {
+                       if(strcmp(argv[i], "-serif") == 0) {
+                               serif = 1;
+                       } else if(strcmp(argv[i], "-sans") == 0) {
+                               serif = 0;
+                       } else if(strcmp(argv[i], "-size") == 0) {
+                               if(!argv[++i] || !(fontsz = atoi(argv[i]))) {
+                                       fprintf(stderr, "-size must be followed by the font size\n");
+                                       return 1;
+                               }
+                       } else if(strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0) {
+                               printf(usage_fmt, argv[0]);
+                               return 0;
+                       } else {
+                               fprintf(stderr, "invalid option: %s\n", argv[i]);
+                               return -1;
+                       }
+               } else {
+                       fprintf(stderr, "unknown argument: %s\n", argv[i]);
+                       return -1;
+               }
+       }
+
+       if(serif) {
+               switch(fontsz) {
+               case 10:
+                       font = GLUT_BITMAP_TIMES_ROMAN_10;
+                       break;
+               case 24:
+                       font = GLUT_BITMAP_TIMES_ROMAN_24;
+                       break;
+               default:
+                       fprintf(stderr, "serif %d not available (only 10, 24)\n", fontsz);
+                       return -1;
+               }
+       } else {
+               switch(fontsz) {
+               case 10:
+                       font = GLUT_BITMAP_HELVETICA_10;
+                       break;
+               case 12:
+                       font = GLUT_BITMAP_HELVETICA_12;
+                       break;
+               case 18:
+                       font = GLUT_BITMAP_HELVETICA_18;
+                       break;
+               default:
+                       fprintf(stderr, "sans %d not available (only 10, 12, 18)\n", fontsz);
+                       return -1;
+               }
+       }
+
+       glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+       glutCreateWindow("fontconv");
+
+       glutDisplayFunc(display);
+       glutReshapeFunc(reshape);
+       glutKeyboardFunc(keyboard);
+
+       glutMainLoop();
+       return 0;
+}
+
+void display(void)
+{
+       int i, x, y;
+       struct glyph *g;
+
+       glClear(GL_COLOR_BUFFER_BIT);
+
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+
+       x = 0;
+       y = win_height - fontsz;
+
+       num_glyphs = 0;
+
+       glRasterPos2i(x, y);
+       for(i=32; i<128; i++) {
+               int width = glutBitmapWidth(font, i);
+               if(x + width >= win_width) {
+                       x = 0;
+                       y -= fontsz;
+                       glRasterPos2i(x, y);
+               }
+
+               g = glyphs + num_glyphs++;
+               g->code = i;
+               g->x = x;
+               g->y = y;
+               g->width = width;
+               g->height = fontsz;
+
+               glutBitmapCharacter(font, i);
+               x += width;
+       }
+
+       if(y < 0) {
+               glutReshapeWindow(win_width, win_height * 2);
+       } else if(y >= win_height / 2) {
+               glutReshapeWindow(win_width, win_height / 2);
+       }
+
+       glReadPixels(0, 0, win_width, win_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, glyphmap);
+
+       glutSwapBuffers();
+}
+
+void reshape(int x, int y)
+{
+       char buf[128];
+
+       free(glyphmap);
+       glyphmap = malloc(x * y);
+
+       glViewport(0, 0, x, y);
+
+       win_width = x;
+       win_height = y;
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrtho(0, x, 0, y, -1, 1);
+
+       sprintf(buf, "fontconv (%dx%d)", x, y);
+       glutSetWindowTitle(buf);
+}
+
+void keyboard(unsigned char key, int x, int y)
+{
+       switch(key) {
+       case 27:
+               exit(0);
+
+       case '=':
+               if(win_width < 1024) {
+                       glutReshapeWindow(win_width * 2, win_height);
+               }
+               break;
+       case '-':
+               if(win_width > 2) {
+                       glutReshapeWindow(win_width / 2, win_height);
+               }
+               break;
+
+       case 's':
+               printf("saving glyphmap (%dx%d): font.pgm\n", win_width, win_height);
+               save_image("font.pgm", win_width, win_height, glyphmap);
+
+               printf("saving metrics: font.metrics\n");
+               save_metrics("font.metrics", glyphs, num_glyphs);
+       }
+}
+
+int save_image(const char *fname, int width, int height, unsigned char *img)
+{
+       FILE *fp;
+
+       if(!(fp = fopen(fname, "wb"))) {
+               fprintf(stderr, "failed to open output file: %s: %s\n", fname, strerror(errno));
+               return -1;
+       }
+       fprintf(fp, "P5\n%d %d\n255\n", width, height);
+       fwrite(img, win_width * win_height, 1, fp);
+       fclose(fp);
+       return 0;
+}
+
+int save_metrics(const char *fname, struct glyph *glyphs, int num_glyphs)
+{
+       FILE *fp;
+       int i;
+
+       if(!(fp = fopen(fname, "wb"))) {
+               fprintf(stderr, "failed to open output file: %s: %s\n", fname, strerror(errno));
+               return -1;
+       }
+
+       fprintf(fp, "MLBFONT1\n");
+       fprintf(fp, "map: font.pgm\n");
+       fprintf(fp, "height: %d\n", fontsz);
+       fprintf(fp, "baseline: %d\n", baseline);
+
+       for(i=0; i<num_glyphs; i++) {
+               fprintf(fp, "%d: %dx%d%+d%+d\n", glyphs->code, glyphs->width,
+                               glyphs->height, glyphs->x, glyphs->y);
+               glyphs++;
+       }
+       fclose(fp);
+       return 0;
+}