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];
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");
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)
{