chiark / gitweb /
Very rough but apparently functional 'palt' support
authorBen Harris <bjh21@bjh21.me.uk>
Fri, 8 Nov 2024 00:42:42 +0000 (00:42 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Thu, 14 Nov 2024 22:27:18 +0000 (22:27 +0000)
bedstead.c

index 9f6c8091ddd6a1d044e13ee3e9e74dfa2eaec341..a88e0b342ad9830f249c301f4e393d69b53c4425 100644 (file)
@@ -3053,6 +3053,13 @@ main(int argc, char **argv)
        TTXI("minMemType1", 0); TTXI("maxMemType1", 0);
        printf(" </post>\n");
 
+       for (i = 0; i < nglyphs; i++)
+               glyphs_by_name[i] = glyphs + i;
+       qsort(glyphs_by_name, nglyphs, sizeof(glyphs_by_name[0]),
+             &compare_glyphs_by_name);
+
+       dogpos(); /* Must be before 'CFF ' because it uses glyph bitmaps. */
+
        printf(" <CFF>\n");
        TTXI("major", 1); TTXI("minor", 0);
        printf("  <CFFFont name='%s'>\n",
@@ -3085,13 +3092,6 @@ main(int argc, char **argv)
        /*      printf("StrokedFont: 1\n"); */
        /*      printf("StrokeWidth: 50\n"); */
        /* } */
-       /* printf("Lookup: 257 0 0 \"palt: proportional metrics\" {\"palt\"} " */
-       /*     "['palt' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n"); */
-       for (i = 0; i < nglyphs; i++)
-               glyphs_by_name[i] = glyphs + i;
-       qsort(glyphs_by_name, nglyphs, sizeof(glyphs_by_name[0]),
-             &compare_glyphs_by_name);
-       /* Scan for aliased glyphs to turn into subroutines. */
        printf("    <Subrs>\n");
        nsubrs = 0;
        for (i = 0; i < nglyphs; i++) {
@@ -3128,7 +3128,6 @@ main(int argc, char **argv)
                       (int)realglyph(&glyphs[i])->left_sidebearing);
        printf(" </hmtx>\n");
        dogsub();
-       dogpos();
        printf("</ttFont>\n");
        return EXIT_SUCCESS;
 }
@@ -3408,10 +3407,20 @@ dosinglesubs(char const *suffix)
                               glyphs[i].name, glyphs[i].name);
 }
 
+static int
+glyph_footprint(char data[XSIZE-1])
+{
+       int i;
+       int footprint = 0;
+
+       for (i = 0; i < YSIZE-1; i++) footprint |= data[i];
+       return footprint;
+}
 
 static void
 dogpos(void)
 {
+       int dx, dh, i;
 
        /* We only support one 'GPOS' lookup, 'palt'. */
        printf(" <GPOS>\n");
@@ -3424,6 +3433,13 @@ dogpos(void)
        TTXI("FeatureIndex", 0);
        printf("    </DefaultLangSys></Script>\n");
        printf("   </ScriptRecord>\n");
+       printf("   <ScriptRecord>\n");
+       TTXS("ScriptTag", "latn");
+       printf("    <Script><DefaultLangSys>\n");
+       TTXI("ReqFeatureIndex", 0xffff); /* No required feature. */
+       TTXI("FeatureIndex", 0);
+       printf("    </DefaultLangSys></Script>\n");
+       printf("   </ScriptRecord>\n");
        printf("  </ScriptList>\n");
        printf("  <FeatureList>\n");
        printf("   <FeatureRecord>\n");
@@ -3437,6 +3453,37 @@ dogpos(void)
        printf("   <Lookup>\n");
        TTXI("LookupType", 1);
        TTXI("LookupFlag", 0);
+       /*
+        * We have only a few dx/dh combinations, so it makes sense to
+        * organise by that rather than spitting out a separate value
+        * for each glyph.
+        */
+       for (dx = 0; dx < XSIZE - 1; dx++)
+               for (dh = (dx == 0 ? 1 : dx); dh < XSIZE - 1; dh++) {
+                       printf("       <SinglePos Format='1'>\n");
+                       printf("<!-- dx = %d; dh = %d -->\n", dx, dh);
+                       printf("        <Coverage>\n");
+                       for (i = 0; i < nglyphs; i++) {
+                               struct glyph *g = realglyph(&glyphs[i]);
+                               if (g->flags & (MOS6|MOS4)) continue;
+                               int fp = glyph_footprint(g->data);
+                               if ((fp & (0xff << (XSIZE-dx-1))) == 0 &&
+                                   (fp & (0xff << (XSIZE-dx-2))) != 0 &&
+                                   (fp & ((1 << (dh - dx)) - 1)) == 0 &&
+                                   (fp & ((1 << (dh - dx + 1)) - 1)) != 0 ||
+                                   fp == 0 && dx == 0 && dh == 3) {
+                                       printf("<!-- fp = 0%o -->\n", fp);
+                                       TTXS("Glyph", glyphs[i].name);
+                               }
+                       }
+                       printf("        </Coverage>\n");
+                       TTXI("ValueFormat", 5);
+                       printf("        <Value XPlacement='%i' "
+                              "XAdvance='%i'/>\n",
+                              (int)(-dx * XPIX), (int)(-dh * XPIX));
+                       printf("       </SinglePos>\n");
+               }
+                       
        printf("   </Lookup>\n");
        printf("  </LookupList>\n");
        printf(" </GPOS>\n");
@@ -3461,40 +3508,6 @@ doglyph(struct glyph *g)
                dochar(g);
 }
 
-static void
-dopalt(struct glyph *g)
-{
-       int i;
-       unsigned char cols = 0;
-       int dx = 0, dh = 0;
-
-       g = realglyph(g);
-       if (g->flags & (MOS6|MOS4)) return;
-       /*
-        * For proportional layout, we'd like a left side-bearing of
-        * one pixel, and a right side-bearing of zero.  Space
-        * characters get an advance width of three pixels.
-        */
-       for (i = 0; i < YSIZE - 1; i++)
-               cols |= g->data[i] & ((1 << XSIZE) - 1);
-       if (cols == 0)
-               dh = 3 - XSIZE;
-       else {
-               while (!(cols & 1 << (XSIZE - 2))) {
-                       cols <<= 1;
-                       dx--;
-               }
-               while (!(cols & 1)) {
-                       cols >>= 1;
-                       dh--;
-               }
-       }
-       if (dx || dh)
-               printf("Position2: \"palt\" dx=%d dy=0 dh=%d dv=0\n",
-                      (int)(dx * XPIX), (int)(dh * XPIX));
-}
-
-
 typedef struct vec {
        int x, y;
 } vec;