Generate PANOSE classification.

This is a mandatory part of the 'OS/2' table, so we may as well get it 
right.  Gratuitously generalised across all possible character widths.
This commit is contained in:
Ben Harris 2017-06-28 22:15:02 +01:00
parent 2a9b39169b
commit 4ca14615e4

View File

@ -157,6 +157,7 @@ struct param *param = &default_param;
void doprologue(void);
void dochar(char const data[YSIZE], unsigned flags);
static void domosaic(unsigned code, bool sep);
static void dopanose();
struct glyph {
char data[YSIZE];
@ -1263,6 +1264,7 @@ main(int argc, char **argv)
printf("OS2SubYOff: %d\n", 2 * YPIX);
printf("OS2SupYOff: %d\n", 2 * YPIX);
printf("TTFWidth: %d\n", param->ttfwidth);
dopanose();
printf("LayerCount: 2\n");
printf("Layer: 0 0 \"Back\" 1\n");
printf("Layer: 1 0 \"Fore\" 0\n");
@ -1323,6 +1325,114 @@ main(int argc, char **argv)
return 0;
}
static void
dopanose()
{
/*
* PANOSE is a complex font categorisation scheme. I suspect
* no-one uses it, but it's a mandatory part of the 'OS/2'
* table, so it would be nice to get it right. This procedure
* calculates the PANOSE code for a Bedstead variant based on
* its design parameters.
*
* See <http://panose.com> for the full details.
*/
int panose[10];
/* Common digits */
/* WeightRat == 700/XPIX */
if (XPIX <= 20) /* WeightRat >= 35 */
panose[2] = 2; /* Very Light */
else if (XPIX < 39) /* WeightRat > 17.9 */
panose[2] = 3; /* Light */
else if (XPIX <= 70) /* WeightRat >= 10 */
panose[2] = 4; /* Thin */
else if (XPIX <= 94) /* WeightRat > 7.44 */
panose[2] = 5; /* Book */
else if (XPIX < 128) /* WeightRat > 5.5 */
panose[2] = 6; /* Medium */
else if (XPIX < 156) /* WeightRat > 4.5 */
panose[2] = 7; /* Demi */
else if (XPIX <= 200) /* WeightRat >= 3.5 */
panose[2] = 8; /* Bold */
else if (XPIX <= 280) /* WeightRat >= 2.5 */
panose[2] = 9; /* Heavy */
else if (XPIX <= 350) /* WeightRat >= 2.0 */
panose[2] = 10; /* Black */
else
panose[2] = 11; /* Extra Black */
/*
* To make life simpler, ignore diagonals when calculating
* ConRat.
*/
/* ConRat == min(XPIX / 100, 100 / XPIX) */
if (XPIX > 80 && XPIX < 125)
panose[4] = 2; /* None */
else if (XPIX > 65 && XPIX < 154)
panose[4] = 3; /* Very Low */
else if (XPIX > 48 && XPIX < 209)
panose[4] = 4; /* Low */
else if (XPIX > 30 && XPIX < 334)
panose[4] = 5; /* Medium Low */
else if (XPIX > 20 && XPIX < 500)
panose[4] = 6; /* Medium */
else if (XPIX > 15 && XPIX < 667)
panose[4] = 7; /* Medium High */
else if (XPIX > 8 && XPIX < 1250)
panose[4] = 8; /* High */
else
panose[4] = 9; /* Very High */
/*
* First digit is overall style. Bedstead is a text font, but
* PANOSE says that fonts with horizontal stress and extreme
* aspect ratios should be classified as decorative.
*/
if (XPIX < 100 || /* ConRat > 1.00 */
XPIX > 164) { /* ORat < 0.85 */
panose[0] = 4; /* Latin Decorative */
panose[1] = 2; /* Derivative */
/* ORat == 140/XPIX */
if (XPIX <= 53)
panose[3] = 2; /* Super Condensed */
else if (XPIX <= 66)
panose[3] = 3; /* Very Condensed */
else if (XPIX <= 110)
panose[3] = 4; /* Condensed */
else if (XPIX <= 152)
panose[3] = 5; /* Normal */
else if (XPIX <= 155)
panose[3] = 6; /* Extended */
else if (XPIX <= 164)
panose[3] = 7; /* Very Extended */
else
panose[3] = 8; /* Super Extended */
panose[5] = 11; /* Normal Sans Serif */
panose[6] = 2; /* Standard Solid Fill */
panose[7] = 2; /* No Lining */
panose[8] = 3; /* Square */
panose[9] = 2; /* Extended Collection */
} else {
panose[0] = 2; /* Latin Text */
panose[1] = 11; /* Normal Sans Serif */
/* J and M are the same width. */
panose[3] = 9; /* Monospaced */
if (panose[4] == 2)
panose[5] = 2; /* No Variation */
else if (XPIX > 100)
panose[5] = 5; /* Gradual/Vertical */
else
panose[5] = 6; /* Gradual/Hoizontal */
/* Unusually shaped 'A' means no fit here. */
panose[6] = 1; /* No Fit */
/* OutCurv == 0.791 */
panose[7] = 5; /* Normal/Boxed */
panose[8] = 3; /* Standard/Pointed */
panose[9] = 7; /* Ducking/Large */
}
printf("Panose: %d %d %d %d %d %d %d %d %d %d\n",
panose[0], panose[1], panose[2], panose[3], panose[4],
panose[5], panose[6], panose[7], panose[8], panose[9]);
}
static void
dopalt(struct glyph const *g)
{