shithub: neatmkfn

Download patch

ref: 27fd6f2204e2990046efb20819ae2abac4de6d83
parent: 26b0c8143db78e9594fb9e6ac455e4a4218d704e
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Dec 10 13:22:49 EST 2016

otf: mark-to-base attachment positioning GPOS subtable

--- a/otf.c
+++ b/otf.c
@@ -461,6 +461,54 @@
 	}
 }
 
+/* mark-to-base attachment positioning */
+static void otf_gpostype4(void *otf, void *sub, char *feat)
+{
+	int fmt = U16(sub, 0);
+	int mcov[NGLYPHS];	/* mark coverage */
+	int bcov[NGLYPHS];	/* base coverage */
+	int cgrp[1024];		/* glyph groups assigned to classes */
+	int bgrp;		/* the group assigned to base glyphs */
+	int mcnt;		/* mark coverage size */
+	int bcnt;		/* base coverage size */
+	int ccnt;		/* class count */
+	void *marks;		/* mark array table */
+	void *bases;		/* base array table */
+	int i, j;
+	if (fmt != 1)
+		return;
+	mcnt = coverage(sub + U16(sub, 2), mcov);
+	bcnt = coverage(sub + U16(sub, 4), bcov);
+	ccnt = U16(sub, 6);
+	marks = sub + U16(sub, 8);
+	bases = sub + U16(sub, 10);
+	bgrp = ggrp_coverage(bcov, bcnt);
+	for (i = 0; i < ccnt; i++) {
+		int grp[NGLYPHS];
+		int cnt = 0;
+		for (j = 0; j < mcnt; j++)
+			if (U16(marks, 2 + 4 * j) == i)
+				grp[cnt++] = mcov[j];
+		cgrp[i] = ggrp_coverage(grp, cnt);
+	}
+	for (i = 0; i < mcnt; i++) {
+		void *mark = marks + U16(marks, 2 + 4 * i + 2);	/* mark anchor */
+		int dx = -uwid(S16(mark, 2));
+		int dy = uwid(S16(mark, 4));
+		printf("gpos %s 2 @%d %s:%+d%+d%+d%+d\n",
+			feat, bgrp, glyph_name[mcov[i]], dx, dy, 0, 0);
+	}
+	for (i = 0; i < bcnt; i++) {
+		for (j = 0; j < ccnt; j++) {
+			void *base = bases + U16(bases, 2 + ccnt * 2 * i + 2 * j);
+			int dx = uwid(S16(base, 2));
+			int dy = -uwid(S16(base, 4));
+			printf("gpos %s 2 %s @%d:%+d%+d%+d%+d\n",
+				feat, glyph_name[bcov[i]], cgrp[j], dx, dy, 0, 0);
+		}
+	}
+}
+
 /* gsub context */
 struct gctx {
 	int bgrp[GCTXLEN];	/* backtrack coverage arrays */
@@ -740,6 +788,9 @@
 				break;
 			case 3:
 				otf_gpostype3(otf, tab, tag);
+				break;
+			case 4:
+				otf_gpostype4(otf, tab, tag);
 				break;
 			default:
 				otf_unsupported("GPOS", type, 0);