shithub: riscv

Download patch

ref: 4b507ed83d4082d7001a1b8b78e7338c2beb2c38
parent: d31f6261b33c5bff12243b05ec752887dbffe019
author: aiju <devnull@localhost>
date: Tue Oct 16 15:14:19 EDT 2018

libttf: add SHZ[] instruction

--- a/sys/src/libttf/hint.c
+++ b/sys/src/libttf/hint.c
@@ -120,7 +120,7 @@
 		if(h->g == nil)
 			herror(h, "access to glyph zone from FPGM/CVT");
 		if((uint)pi >= h->g->npt)
-			herror(h, "glyph zone point index %d out of range", n);
+			herror(h, "glyph zone point index %d out of range", pi);
 		dprint("G%s%d: %+π\n", n&ORIG?"O":"", pi, (n & ORIG) != 0 ? h->g->ptorg[pi] : h->g->pt[pi]);
 		return (n & ORIG) != 0 ? h->g->ptorg[pi] : h->g->pt[pi];
 	}else{
@@ -143,18 +143,54 @@
 		if(h->g == nil)
 			herror(h, "access to glyph zone from FPGM/CVT");
 		if((uint)pi >= h->g->npt)
-			herror(h, "glyph zone point index %d out of range", n);
+			herror(h, "glyph zone point index %d out of range", pi);
 		dprint("G%d: %+π -> %+π\n", pi, h->g->pt[pi], p);
 		h->g->pt[pi] = p;
 	}else{
 		if((uint)pi >= h->f->u->maxTwilightPoints)
-			herror(h, "twilight zone point index %d out of range", n);
+			herror(h, "twilight zone point index %d out of range", pi);
 		dprint("T%d: %+π -> %+π\n", pi, h->f->twilight[pi], p);
 		h->f->twilight[pi] = p;
 	}
 }
 
+static TTPoint
+getpointz(Hint *h, int z, int pi)
+{
+	if((z & 1) != 0){
+		if(h->g == nil)
+			herror(h, "access to glyph zone from FPGM/CVT");
+		if((uint)pi >= h->g->npt)
+			herror(h, "glyph zone point index %d out of range", pi);
+		dprint("G%s%d: %+π\n", z&ORIG?"O":"", pi, (z & ORIG) != 0 ? h->g->ptorg[pi] : h->g->pt[pi]);
+		return (z & ORIG) != 0 ? h->g->ptorg[pi] : h->g->pt[pi];
+	}else{
+		if((uint)pi >= h->f->u->maxTwilightPoints)
+			herror(h, "twilight zone point index %d out of range", pi);
+		return (z & ORIG) != 0 ? h->f->twiorg[pi] : h->f->twilight[pi];
+	}
+}
+
 static void
+setpointz(Hint *h, int z, int pi, TTPoint p)
+{
+	if((z & 1) != 0){
+		if(h->g == nil)
+			herror(h, "access to glyph zone from FPGM/CVT");
+		if((uint)pi >= h->g->npt)
+			herror(h, "glyph zone point index %d out of range", pi);
+		dprint("G%d: %+π -> %+π\n", pi, h->g->pt[pi], p);
+		h->g->pt[pi] = p;
+	}else{
+		if((uint)pi >= h->f->u->maxTwilightPoints)
+			herror(h, "twilight zone point index %d out of range", pi);
+		dprint("T%d: %+π -> %+π\n", pi, h->f->twilight[pi], p);
+		h->f->twilight[pi] = p;
+	}
+}
+
+
+static void
 debugprint(Hint *h, int skip)
 {
 	Fmt f;
@@ -1445,6 +1481,34 @@
 	}
 }
 
+static void
+h_shz(Hint *h)
+{
+	int i, e, np;
+	TTPoint rp, orp;
+	TTPoint p, n;
+	int d, dp;
+
+	if((h->ip[-1] & 1) != 0){
+		rp = getpoint(h, RP1|ZP0, 0);
+		orp = getpoint(h, RP1|ZP0|ORIG, 0);
+	}else{
+		rp = getpoint(h, RP2|ZP1, 0);
+		orp = getpoint(h, RP2|ZP1|ORIG, 0);
+	}
+	e = pop(h);
+	if((uint)e > 1)
+		herror(h, "SHZ[] with invalid zone %d", e);
+	d = project(h, &rp, &orp);
+	np = e ? h->g->npt : h->f->u->maxTwilightPoints;
+	for(i = 0; i < np; i++){
+		p = getpointz(h, e, i);
+		dp = project(h, &p, nil);
+		n = forceproject(h, p, dp + d);
+		setpointz(h, e, i, n);
+	}
+}
+
 static void (*itable[256])(Hint *) = {
 	[0x00] h_svtca, h_svtca, h_svtca, h_svtca, h_svtca, h_svtca,
 	[0x06] h_sxvtl, h_sxvtl, h_sxvtl, h_sxvtl,
@@ -1478,6 +1542,7 @@
 	[0x30] h_iup, h_iup,
 	[0x32] h_shp, h_shp,
 	[0x34] h_shc, h_shc,
+	[0x37] h_shz,
 	[0x38] h_shpix,
 	[0x39] h_ip,
 	[0x3a] h_msirp, h_msirp,