shithub: fnt

Download patch

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

otfdrawglyf: add horizontal and vertical glyph scaling

--- a/otf.h.in
+++ b/otf.h.in
@@ -109,4 +109,4 @@
 Rune otfglyph2rune(Otf *o, int g);
 
 Glyf *otfglyf(Otf *o, int index);
-GlyfImage *otfdrawglyf(Otf *o, Glyf *g, double ppem);
+GlyfImage *otfdrawglyf(Otf *o, Glyf *g, double ppem, double scaleX, double scaleY);
--- a/plan9/otf.h
+++ b/plan9/otf.h
@@ -110,7 +110,7 @@
 Rune otfglyph2rune(Otf *o, int g);
 
 Glyf *otfglyf(Otf *o, int index);
-GlyfImage *otfdrawglyf(Otf *o, Glyf *g, double ppem);
+GlyfImage *otfdrawglyf(Otf *o, Glyf *g, double ppem, double scaleX, double scaleY);
 
 typedef struct SubHeader SubHeader;
 typedef struct MapGroup MapGroup;
--- a/rast.c
+++ b/rast.c
@@ -548,15 +548,15 @@
 }
 
 GlyfImage *
-otfdrawglyf(Otf *o, Glyf *g, double ppem)
+otfdrawglyf(Otf *o, Glyf *g, double ppem, double scaleX, double scaleY)
 {
 	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];
+	Sval offY;
 	Spt *pts;
 
 	ngs = 0;
@@ -589,15 +589,16 @@
 */
 
 	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;
+	scaleX *= ppem / o->td.head->unitsPerEm;
+	scaleY *= ppem / o->td.head->unitsPerEm;
+	bb[0] = g->xMin*scaleX;
+	bb[1] = g->yMin*scaleY;
+	bb[2] = g->xMax*scaleX;
+	bb[3] = g->yMax*scaleY;
 	s = s₀ = (SegQ*)(pts + maxpts);
 	cg = g->component;
 	for(i = 0; i < ngs; i++){
-		Sval dx = 0, dy = 0, gscaleX = scale, gscaleY = scale;
+		Sval dx = 0, dy = 0, gscaleX = scaleX, gscaleY = scaleY;
 		if(cg != nil){
 			if(cg->flags & CGLYPH_FL_SIGNED_XY){
 				dx = cg->dx;
@@ -614,8 +615,8 @@
 				dx *= gscaleX;
 				dy *= gscaleY;
 			}else{
-				dx *= scale;
-				dy *= scale;
+				dx *= scaleX;
+				dy *= scaleY;
 			}
 /* FIXME rounding
 			if(cg->flags & CGLYPH_FL_ROUND_TO_GRID_XY){
--- a/test.h
+++ b/test.h
@@ -10,12 +10,14 @@
 	f->print(f->aux, " -m: print out glyph ids or render them all as a map (with -p)\n");
 	f->print(f->aux, " -R: ignore glyphs that do not represent valid runes\n");
 	f->print(f->aux, " -H: highlight a specific glyph in the map by its ID\n");
+	f->print(f->aux, " -x: horizontal scale factor\n");
+	f->print(f->aux, " -y: vertical scale factor\n");
 	f->print(f->aux, "Specifying -m more than once adds guide lines\n");
 	f->print(f->aux, "Specifying -m more than twice makes empty pixels filled out\n");
 }
 
 static int gind = -1, map, highlight = -1, runesonly;
-static double ppem;
+static double ppem, scaleX = 1, scaleY = 1;
 static Rune rune = NoRune;
 
 static int
@@ -76,6 +78,8 @@
 			break;
 
 		for(x = 0; i < j; i++){
+			if(im[i] == 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){
@@ -148,7 +152,7 @@
 				return -1;
 			}
 			if(ppem > 0 && g->numberOfContours != 0){
-				if((im[i] = otfdrawglyf(o, g, ppem)) == nil)
+				if((im[i] = otfdrawglyf(o, g, ppem, scaleX, scaleY)) == nil)
 					goto glypherr;
 			}else if(ppem <= 0){
 				out->print(out->aux, "%d (%s):\n", i,
@@ -171,7 +175,7 @@
 			goto glypherr;
 		}else if(ppem > 0){
 			GlyfImage *im;
-			if((im = otfdrawglyf(o, g, ppem)) == nil)
+			if((im = otfdrawglyf(o, g, ppem, scaleX, scaleY)) == nil)
 				goto glypherr;
 			if(out->write != otfdiscard && dumpmap(out, &im, 1) != 0)
 				return -1;
@@ -217,6 +221,12 @@
 		} break; \
 	case 'R': \
 		runesonly++; \
+		break; \
+	case 'x': \
+		scaleX = strtod(EARGF(usage(&out)), nil); \
+		break; \
+	case 'y': \
+		scaleY = strtod(EARGF(usage(&out)), nil); \
 		break; \
 	default: \
 		usage(&out); \
--