From: Ben Harris Date: Tue, 1 Aug 2017 22:27:22 +0000 (+0100) Subject: Mechanisms to get metadata right for different weights of font. X-Git-Tag: bedstead-002.000~100 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~bjharris/git?a=commitdiff_plain;h=e40c1419a3a048f05dd8424c4c8d932fffb2db0a;p=bedstead-debian.git Mechanisms to get metadata right for different weights of font. bedstead.c can now generate Bedstead Book (and all other widths at that weight). --- diff --git a/bedstead.c b/bedstead.c index 4ade039..722410d 100644 --- a/bedstead.c +++ b/bedstead.c @@ -127,43 +127,43 @@ static struct width { char const * option; - char const * fullname; + char const * suffix; int xpix; int ttfwidth; } const widths[] = { { "--normal", - "Bedstead", + "", 100, /* xpix */ 5, /* ttfwidth */ }, { "--ultra-condensed", - "Bedstead Ultra Condensed", + " Ultra Condensed", 50, /* xpix */ 1, /* ttfwidth */ }, { "--extra-condensed", - "Bedstead Extra Condensed", + " Extra Condensed", 62, /* xpix */ 2, /* ttfwidth */ }, { "--condensed", - "Bedstead Condensed", + " Condensed", 76, /* xpix */ 3, /* ttfwidth */ }, { "--semi-condensed", - "Bedstead Semi Condensed", + " Semi Condensed", 88, /* xpix */ 4, /* ttfwidth */ }, { "--extended", - "Bedstead Extended", + " Extended", 124, /* xpix */ 7, /* ttfwidth */ }, @@ -172,6 +172,30 @@ static int const nwidths = sizeof(widths) / sizeof(widths[0]); struct width const *width = &widths[0]; +static struct weight { + char const *option; + char const *suffix; + int weight; /* Expressed in internal units */ + int ttfweight; +} const weights[] = { + { + "--medium", + "", + 0, + 500, + }, + { + "--book", + " Book", + -25, + 400, + }, +}; + +static int const nweights = sizeof(weights) / sizeof(weights[0]); + +struct weight const *weight = &weights[0]; + /* Size of output pixels in font design units (usually 1000/em) */ #define XPIX (width->xpix) #define YPIX 100 @@ -1263,6 +1287,15 @@ getpix(char const data[YSIZE], int x, int y, unsigned flags) static bool plottermode = false; +static char * get_fullname() +{ +#define FULLNAME_MAX 100 + static char fullname[FULLNAME_MAX]; + + sprintf(fullname, "Bedstead%s%s", weight->suffix, width->suffix); + return fullname; +} + static char * fullname_to_fontname(char const *fullname) { #define FONTNAME_MAX 29 /* Adobe-recommended limit */ @@ -1298,7 +1331,6 @@ main(int argc, char **argv) return 0; } - while (argc > 1) { for (i = 0; i < nwidths; i++) if (strcmp(argv[1], widths[i].option) == 0) { @@ -1306,6 +1338,12 @@ main(int argc, char **argv) argv++; argc--; goto next; } + for (i = 0; i < nweights; i++) + if (strcmp(argv[1], weights[i].option) == 0) { + weight = &weights[i]; + argv++; argc--; + goto next; + } if (strcmp(argv[1], "--plotter") == 0) { plottermode = true; argv++; argc--; @@ -1350,10 +1388,10 @@ main(int argc, char **argv) if (glyphs[i].unicode == -1) extraglyphs++; printf("SplineFontDB: 3.0\n"); - printf("FontName: %s\n", fullname_to_fontname(width->fullname)); - printf("FullName: %s\n", width->fullname); + printf("FontName: %s\n", fullname_to_fontname(get_fullname())); + printf("FullName: %s\n", get_fullname()); printf("FamilyName: Bedstead\n"); - printf("Weight: Medium\n"); + printf("Weight:%s\n", weight->suffix[0] ? weight->suffix : " Medium"); printf("OS2_WeightWidthSlopeOnly: 1\n"); printf("Copyright: Dedicated to the public domain\n"); printf("Version: 001.003\n"); @@ -1374,7 +1412,7 @@ main(int argc, char **argv) printf("OS2SubYOff: %d\n", 2 * YPIX); printf("OS2SupYOff: %d\n", 2 * YPIX); printf("FSType: 0\n"); - printf("TTFWeight: 500\n"); + printf("TTFWeight: %d\n", weight->ttfweight); printf("TTFWidth: %d\n", width->ttfwidth); dopanose(); printf("OS2FamilyClass: %d\n", 0x080a); @@ -1392,7 +1430,7 @@ main(int argc, char **argv) } printf("BeginPrivate: 2\n"); printf(" StdHW 5 [%d]\n", YPIX); - printf(" StdVW 5 [%d]\n", XPIX); + printf(" StdVW 5 [%d]\n", XPIX * (100 + weight->weight) / 100); printf("EndPrivate\n"); /* Force monochrome at 10 and 20 pixels, and greyscale elsewhere. */ printf("GaspTable: 5 9 2 10 0 19 3 20 0 65535 3\n"); @@ -1459,25 +1497,27 @@ dopanose() * See for the full details. */ int panose[10]; + int stdvw; /* Common digits */ - /* WeightRat == 700/XPIX */ - if (XPIX <= 20) /* WeightRat >= 35 */ + /* WeightRat == 700/StdVW */ + stdvw = XPIX * (100 + weight->weight) / 100; + if (stdvw <= 20) /* WeightRat >= 35 */ panose[2] = 2; /* Very Light */ - else if (XPIX < 39) /* WeightRat > 17.9 */ + else if (stdvw < 39) /* WeightRat > 17.9 */ panose[2] = 3; /* Light */ - else if (XPIX <= 70) /* WeightRat >= 10 */ + else if (stdvw <= 70) /* WeightRat >= 10 */ panose[2] = 4; /* Thin */ - else if (XPIX <= 94) /* WeightRat > 7.44 */ + else if (stdvw <= 94) /* WeightRat > 7.44 */ panose[2] = 5; /* Book */ - else if (XPIX < 128) /* WeightRat > 5.5 */ + else if (stdvw < 128) /* WeightRat > 5.5 */ panose[2] = 6; /* Medium */ - else if (XPIX < 156) /* WeightRat > 4.5 */ + else if (stdvw < 156) /* WeightRat > 4.5 */ panose[2] = 7; /* Demi */ - else if (XPIX <= 200) /* WeightRat >= 3.5 */ + else if (stdvw <= 200) /* WeightRat >= 3.5 */ panose[2] = 8; /* Bold */ - else if (XPIX <= 280) /* WeightRat >= 2.5 */ + else if (stdvw <= 280) /* WeightRat >= 2.5 */ panose[2] = 9; /* Heavy */ - else if (XPIX <= 350) /* WeightRat >= 2.0 */ + else if (stdvw <= 350) /* WeightRat >= 2.0 */ panose[2] = 10; /* Black */ else panose[2] = 11; /* Extra Black */ @@ -1485,20 +1525,20 @@ dopanose() * To make life simpler, ignore diagonals when calculating * ConRat. */ - /* ConRat == min(XPIX / 100, 100 / XPIX) */ - if (XPIX > 80 && XPIX < 125) + /* ConRat == min(StdVW / 100, 100 / StdVW) */ + if (stdvw > 80 && stdvw < 125) panose[4] = 2; /* None */ - else if (XPIX > 65 && XPIX < 154) + else if (stdvw > 65 && stdvw < 154) panose[4] = 3; /* Very Low */ - else if (XPIX > 48 && XPIX < 209) + else if (stdvw > 48 && stdvw < 209) panose[4] = 4; /* Low */ - else if (XPIX > 30 && XPIX < 334) + else if (stdvw > 30 && stdvw < 334) panose[4] = 5; /* Medium Low */ - else if (XPIX > 20 && XPIX < 500) + else if (stdvw > 20 && stdvw < 500) panose[4] = 6; /* Medium */ - else if (XPIX > 15 && XPIX < 667) + else if (stdvw > 15 && stdvw < 667) panose[4] = 7; /* Medium High */ - else if (XPIX > 8 && XPIX < 1250) + else if (stdvw > 8 && stdvw < 1250) panose[4] = 8; /* High */ else panose[4] = 9; /* Very High */ @@ -1507,7 +1547,7 @@ dopanose() * PANOSE says that fonts with horizontal stress and extreme * aspect ratios should be classified as decorative. */ - if (XPIX < 100 || /* ConRat > 1.00 */ + if (stdvw < 100 || /* ConRat > 1.00 */ XPIX > 164) { /* ORat < 0.85 */ panose[0] = 4; /* Latin Decorative */ panose[1] = 2; /* Derivative */ @@ -1538,13 +1578,14 @@ dopanose() panose[3] = 9; /* Monospaced */ if (panose[4] == 2) panose[5] = 2; /* No Variation */ - else if (XPIX > 100) + else if (stdvw > 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 */ + /* FIXME: Only correct for weight == 0 */ panose[7] = 5; /* Normal/Boxed */ panose[8] = 3; /* Standard/Pointed */ panose[9] = 7; /* Ducking/Large */ @@ -1851,8 +1892,6 @@ emit_path() * don't run out of slack in horizontal lines, which limits weight to * the range (-0.5 * XPIX) < weight < (0.25 * XPIX). */ -static int weight = 0; - static void adjust_weight() { @@ -1865,18 +1904,18 @@ adjust_weight() assert(p->prev != NULL); /* Move left-edge points horizontally */ if (p->prev->v.y <= p->v.y && p->v.y <= p->next->v.y) - p->v.x -= weight; + p->v.x -= weight->weight; /* Move top inner corner points along NE/SW diagonal */ if (p->prev->v.y < p->v.y && p->v.y > p->next->v.y && p->prev->v.x > p->v.x && p->v.x > p->next->v.x) { - p->v.x -= weight/2; - p->v.y -= weight/2; + p->v.x -= weight->weight/2; + p->v.y -= weight->weight/2; } /* Move bottom inner corner points along NW/SE diagonal */ if (p->prev->v.y > p->v.y && p->v.y < p->next->v.y && p->prev->v.x < p->v.x && p->v.x < p->next->v.x) { - p->v.x -= weight/2; - p->v.y += weight/2; + p->v.x -= weight->weight/2; + p->v.y += weight->weight/2; } } }