shithub: fnt

Download patch

ref: 2cfe3c2c1cb0de08ef9a4dca2d22dac286736b09
parent: a557643233703904d5777748ae7166d6d8b612e0
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Jul 22 22:43:20 EDT 2024

make otfdrawglyf itself allocate the image

--- a/otf.h.in
+++ b/otf.h.in
@@ -94,19 +94,19 @@
 
 /* FIXME these might go eventually */
 
+typedef struct Glyf Glyf;
 typedef struct GlyfImage GlyfImage;
 
 struct GlyfImage {
-	u8int *b;
 	int w;
 	int h;
 	int baseline;
+	u8int b[];
 };
 
-typedef struct Glyf Glyf;
-Glyf *otfglyf(Otf *o, int index);
 int otfglyfnum(Otf *o);
-int otfdrawglyf(Otf *o, Glyf *g, double ppem, GlyfImage *im);
-int otfupem(Otf *o);
 int otfrune2glyph(Otf *o, Rune r);
 Rune otfglyph2rune(Otf *o, int g);
+
+Glyf *otfglyf(Otf *o, int index);
+GlyfImage *otfdrawglyf(Otf *o, Glyf *g, double ppem);
--- a/plan9/otf.h
+++ b/plan9/otf.h
@@ -95,22 +95,22 @@
 
 /* FIXME these might go eventually */
 
+typedef struct Glyf Glyf;
 typedef struct GlyfImage GlyfImage;
 
 struct GlyfImage {
-	u8int *b;
 	int w;
 	int h;
 	int baseline;
+	u8int b[];
 };
 
-typedef struct Glyf Glyf;
-Glyf *otfglyf(Otf *o, int index);
 int otfglyfnum(Otf *o);
-int otfdrawglyf(Otf *o, Glyf *g, double ppem, GlyfImage *im);
-int otfupem(Otf *o);
 int otfrune2glyph(Otf *o, Rune r);
 Rune otfglyph2rune(Otf *o, int g);
+
+Glyf *otfglyf(Otf *o, int index);
+GlyfImage *otfdrawglyf(Otf *o, Glyf *g, double ppem);
 
 typedef struct SubHeader SubHeader;
 typedef struct MapGroup MapGroup;
--- a/rast.c
+++ b/rast.c
@@ -547,20 +547,21 @@
 	return npts < 2 ? 0 : npts;
 }
 
-int
-otfdrawglyf(Otf *o, Glyf *g, double ppem, GlyfImage *im)
+GlyfImage *
+otfdrawglyf(Otf *o, Glyf *g, double ppem)
 {
-	int i, j, maxptstotal, maxpts, ngs, w, h, r, npx, baseline;
+	int i, j, maxptstotal, maxpts, ngs, w, h, npx, baseline;
 	Glyf *gs[MAXCOMPONENTS];
 	ComponentGlyph *cg;
 	Sval scale, offY;
 	SegQ *s₀, *s, *p;
+	GlyfImage *im;
+	Sval bb[4];
 	Spt *pts;
-	u8int *b;
 
-	r = -1;
 	ngs = 0;
 	pts = nil;
+	im = nil;
 
 	if(g->simple != nil){
 		gs[ngs++] = g;
@@ -587,9 +588,12 @@
 	}
 */
 
-	scale = ppem / o->td.head->unitsPerEm;
-	Sval bb[4] = {g->xMin*scale, g->yMin*scale, g->xMax*scale, g->yMax*scale};
 	pts = calloc(1, maxpts*sizeof(*pts) + maxptstotal/2*sizeof(*s));
+	scale = ppem / o->td.head->unitsPerEm;
+	bb[0] = g->xMin*scale;
+	bb[1] = g->yMin*scale;
+	bb[2] = g->xMax*scale;
+	bb[3] = g->yMax*scale;
 	s = s₀ = (SegQ*)(pts + maxpts);
 	cg = g->component;
 	for(i = 0; i < ngs; i++){
@@ -656,16 +660,16 @@
 	}
 
 	npx = w*h;
-	b = malloc(npx);
-	b[0] = 0;
-	if(qbzr(s₀, s-s₀, w, h, b) == 0){
-		im->b = b;
+	im = malloc(sizeof(*im) + npx);
+	im->b[0] = 0;
+	if(qbzr(s₀, s-s₀, w, h, im->b) == 0){
 		im->w = w;
 		im->h = h;
 		im->baseline = baseline;
-		r = 0;
-	}else
-		free(b);
+	}else{
+		free(im);
+		im = nil;
+	}
 
 done:
 	for(i = 0; i < ngs; i++){
@@ -673,5 +677,5 @@
 			free(gs[i]);
 	}
 	free(pts);
-	return r;
+	return im;
 }
--- a/test.h
+++ b/test.h
@@ -19,7 +19,7 @@
 static Rune rune = NoRune;
 
 static int
-dumpmap(Otfile *f, GlyfImage *im, int n)
+dumpmap(Otfile *f, GlyfImage **im, int n)
 {
 	int x, y, i, j, t, maxh, prebase, postbase, d, border;
 	int gap, total, mid, npix, bw, bh, lines, fill;
@@ -31,20 +31,20 @@
 	fill = map > 2;
 	if(n == 1){
 		gap = 8;
-		maxh = im->h;
-		if(im->baseline)
-			maxh += im->baseline;
-		bw = 2*gap + im->w;
+		maxh = im[0]->h;
+		if(im[0]->baseline)
+			maxh += im[0]->baseline;
+		bw = 2*gap + im[0]->w;
 		bh = 2*gap + maxh;
 		npix = bw * bh;
 	}else{
 		gap = 1;
 		for(i = 0; i < n; i++){
-			if(im[i].b == nil)
+			if(im[i] == nil)
 				continue;
-			if(maxh < im[i].h)
-				maxh = im[i].h;
-			total += im[i].w;
+			if(maxh < im[i]->h)
+				maxh = im[i]->h;
+			total += im[i]->w;
 		}
 		mid = total / n;
 		npix = (mid+gap)*(maxh+gap)*n;
@@ -61,15 +61,15 @@
 	for(i = 0; i < n;){
 		prebase = postbase = 0;
 		for(x = 0, j = i; j < n; j++){
-			if(im[j].b == nil)
+			if(im[j] == nil)
 				continue;
-			x += im[j].w + gap;
+			x += im[j]->w + gap;
 			if(x > bw)
 				break;
-			if(prebase < im[j].h+im[j].baseline)
-				prebase = im[j].h+im[j].baseline;
-			if(im[j].baseline < 0 && postbase < -im[j].baseline)
-				postbase = -im[j].baseline;
+			if(prebase < im[j]->h+im[j]->baseline)
+				prebase = im[j]->h+im[j]->baseline;
+			if(im[j]->baseline < 0 && postbase < -im[j]->baseline)
+				postbase = -im[j]->baseline;
 		}
 		maxh = prebase + postbase;
 		if(j == i || y+maxh > bh)
@@ -76,16 +76,14 @@
 			break;
 
 		for(x = 0; i < j; i++){
-			if(im[i].b == nil)
-				continue;
-			u8int *lt = b + ((y + prebase - (im[i].h+im[i].baseline))*bw + x)*3;
-			x += im[i].w + gap;
-			for(d = 0; d < im[i].h; d++, lt += bw*3){
-				for(t = 0; t < im[i].w; t++){
+			u8int *lt = b + ((y + prebase - (im[i]->h+im[i]->baseline))*bw + x)*3;
+			x += im[i]->w + gap;
+			for(d = 0; d < im[i]->h; d++, lt += bw*3){
+				for(t = 0; t < im[i]->w; t++){
 					u8int r, g, b;
-					r = g = b = im[i].b[d*im[i].w + t];
-					border = d == 0 || t == 0 || t == im[i].w-1 || d == im[i].h-1;
-					if((lines || highlight == i) && g == 0xff && (d == im[i].h+im[i].baseline)){
+					r = g = b = im[i]->b[d*im[i]->w + t];
+					border = d == 0 || t == 0 || t == im[i]->w-1 || d == im[i]->h-1;
+					if((lines || highlight == i) && g == 0xff && (d == im[i]->h+im[i]->baseline)){
 						g = 0;
 						b = 0;
 					}else if((lines || highlight == i) && g == 0xff && (fill || border)){
@@ -117,7 +115,7 @@
 static int
 process(Otfile *in, Otfile *out)
 {
-	GlyfImage *im;
+	GlyfImage **im;
 	int i, n;
 	Glyf *g;
 	Otf *o;
@@ -150,7 +148,7 @@
 				return -1;
 			}
 			if(ppem > 0 && g->numberOfContours != 0){
-				if(otfdrawglyf(o, g, ppem, im+i) != 0)
+				if((im[i] = otfdrawglyf(o, g, ppem)) == nil)
 					goto glypherr;
 			}else if(ppem <= 0){
 				out->print(out->aux, "%d (%s):\n", i,
@@ -163,7 +161,7 @@
 			if(out->write != otfdiscard && dumpmap(out, im, n) != 0)
 				return -1;
 			for(i = 0; i < n; i++)
-				free(im[i].b);
+				free(im[i]);
 			free(im);
 		}
 	}else if(gind < 0){
@@ -172,12 +170,12 @@
 		if((g = otfglyf(o, gind)) == nil){
 			goto glypherr;
 		}else if(ppem > 0){
-			GlyfImage im;
-			if(otfdrawglyf(o, g, ppem, &im) != 0)
+			GlyfImage *im;
+			if((im = otfdrawglyf(o, g, ppem)) == nil)
 				goto glypherr;
 			if(out->write != otfdiscard && dumpmap(out, &im, 1) != 0)
 				return -1;
-			free(im.b);
+			free(im);
 		}else{
 			out->print(out->aux, "\n%d:\n", gind);
 			print_Glyf(out, indentΔ, o, g);