shithub: fnt

Download patch

ref: 05750074ef073d38c25544958c42891c03dd99a7
parent: 29c96c7ead583a633d3e05b9df1eca529b7d996f
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Jul 11 21:27:10 EDT 2024

dump font map when used as -s SIZE -G

--- a/meson.build
+++ b/meson.build
@@ -27,6 +27,9 @@
 	'test_unix.c',
 ]
 
+cc = meson.get_compiler('c')
+math = cc.find_library('m', required: false)
+
 executable(
 	'fntest',
 	sources: [src],
@@ -33,4 +36,5 @@
 	include_directories: include_directories(
 		'unix',
 	),
+	dependencies: [math],
 )
--- a/test_plan9.c
+++ b/test_plan9.c
@@ -3,6 +3,57 @@
 #include <bio.h>
 #include "otf.h"
 
+typedef struct Image Image;
+
+struct Image {
+	int w;
+	u8int *b;
+};
+
+static void
+fit(u8int *b, int bw, int bh, Image *im, int h, int *x, int *y, int gap)
+{
+	int d;
+
+	if((bw-*x) < im->w+gap){
+		*y += h + gap;
+		*x = gap;
+	}
+	if((bh-*y) < h+gap)
+		return;
+	for(d = 0; d < h; d++)
+		memcpy(b + (*y + d)*bw + *x, im->b + d*im->w, im->w);
+	*x += im->w + gap;
+}
+
+static void
+dumpmap(Biobuf *out, Image *im, int n, int h)
+{
+#define gap 2
+	int total, mid, npix, bw, bh, x, y, i;
+	u8int *b;
+
+	total = 0;
+	for(i = 0; i < n; i++)
+		total += im[i].w;
+	mid = total / n;
+	npix = (mid+gap)*(h+gap)*n;
+	bh = sqrt(npix);
+	bw = npix/bh;
+	bh *= 1.5;
+	npix *= 1.5;
+	npix += bw*gap;
+	if((b = malloc(npix)) == nil)
+		sysfatal("no memory");
+	memset(b, 0xff, npix);
+	x = y = gap;
+	for(i = 0; i < n; i++)
+		fit(b, bw, bh, im+i, h, &x, &y, gap);
+	Bprint(out, "%11s %11d %11d %11d %11d ", "k8", 0, 0, bw, y+h+gap);
+	Bwrite(out, b, bw*(y+h+gap));
+	free(b);
+}
+
 static int
 otfseek(void *aux, int off, int whence)
 {
@@ -63,6 +114,7 @@
 		}
 		if(G){
 			int i, n = otfglyfnum(o);
+			Image *im = h > 0 ? calloc(n, sizeof(*im)) : nil;
 			for(i = 0; i < n; i++){
 				Glyf *g = otfglyf(o, i);
 				if(g != nil && g->simple != nil && g->numberOfContours > 0){
@@ -71,7 +123,8 @@
 						u8int *b = otfdrawglyf(g, h, &w);
 						if(b == nil)
 							sysfatal("%r");
-						free(b);
+						im[i].w = w;
+						im[i].b = b;
 					}else{
 						fprint(2, "%d ", i);
 					}
@@ -78,8 +131,14 @@
 				}
 				free(g);
 			}
-			if(h <= 0)
+			if(h > 0){
+				dumpmap(out.aux, im, n, h);
+				for(i = 0; i < n; i++)
+					free(im[i].b);
+				free(im);
+			}else{
 				fprint(2, "\n");
+			}
 		}else if(gi < 0){
 			otfprint(o, &out, indentΔ);
 		}else{
--- a/test_unix.c
+++ b/test_unix.c
@@ -1,7 +1,62 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <math.h>
 #include "otf.h"
 
+typedef struct Image Image;
+
+struct Image {
+	int w;
+	u8int *b;
+};
+
+static void
+fit(u8int *b, int bw, int bh, Image *im, int h, int *x, int *y, int gap)
+{
+	int d;
+
+	if((bw-*x) < im->w+gap){
+		*y += h + gap;
+		*x = gap;
+	}
+	if((bh-*y) < h+gap)
+		return;
+	for(d = 0; d < h; d++)
+		memcpy(b + (*y + d)*bw + *x, im->b + d*im->w, im->w);
+	*x += im->w + gap;
+}
+
+static void
+dumpmap(FILE *out, Image *im, int n, int h)
+{
+#define gap 2
+	int total, mid, npix, bw, bh, x, y, i;
+	u8int *b;
+
+	total = 0;
+	for(i = 0; i < n; i++)
+		total += im[i].w;
+	mid = total / n;
+	npix = (mid+gap)*(h+gap)*n;
+	bh = sqrt(npix);
+	bw = npix/bh;
+	bh *= 1.5;
+	npix *= 1.5;
+	npix += bw*gap;
+	if((b = malloc(npix)) == NULL){
+		fprintf(stderr, "no memory\n");
+		exit(1);
+	}
+	memset(b, 0xff, npix);
+	x = y = gap;
+	for(i = 0; i < n; i++)
+		fit(b, bw, bh, im+i, h, &x, &y, gap);
+	fprintf(out, "%11s %11d %11d %11d %11d ", "k8", 0, 0, bw, y+h+gap);
+	fwrite(b, 1, bw*(y+h+gap), out);
+	free(b);
+}
+
 static char *argv0;
 
 #define	ARGBEGIN	for((argv0? 0: (argv0=*argv)),argv++,argc--;\
@@ -86,6 +141,7 @@
 		}
 		if(G){
 			int i, n = otfglyfnum(o);
+			Image *im = h > 0 ? calloc(n, sizeof(*im)) : NULL;
 			for(i = 0; i < n; i++){
 				Glyf *g = otfglyf(o, i);
 				if(g != NULL && g->simple != NULL && g->numberOfContours > 0){
@@ -96,7 +152,8 @@
 							fprintf(stderr, "failed\n");
 							exit(1);
 						}
-						free(b);
+						im[i].w = w;
+						im[i].b = b;
 					}else{
 						fprintf(out.aux, "%d ", i);
 					}
@@ -103,8 +160,14 @@
 				}
 				free(g);
 			}
-			if(h <= 0)
+			if(h > 0){
+				dumpmap(out.aux, im, n, h);
+				for(i = 0; i < n; i++)
+					free(im[i].b);
+				free(im);
+			}else{
 				fprintf(out.aux, "\n");
+			}
 		}else if(gi < 0){
 			otfprint(o, &out, indentΔ);
 		}else{