Very rough but apparently functional 'palt' support

This commit is contained in:
Ben Harris 2024-11-08 00:42:42 +00:00
parent 1055dd31f5
commit b83edc5cc0

View 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;