bedstead/bedstead.c
Ben Harris 7ba21188c8 In do_palt(), mask out unused data bits.
This avoids an infinite loop if one of them is inadvertently (or
advertently) set.  Why might one be set advertently?  Well, it would
allow us to replace our long lists of numbers with short strings.  For
instance, the U+0024 DOLLAR SIGN glyph is "NUTNEUN".  Sadly that would
make the program incompatible with non-ASCII systems and since I claim
ANSI C I should probably continue to support those.
2017-07-08 00:51:44 +01:00

1896 lines
85 KiB
C

/*
* Many of the character bitmaps below formed the typeface embodied in
* the SAA5050 series of character-generator chips originally made and
* sold by British company Mullard in the early 1980s. Copyright in the
* typeface will still be owned by Mullard's corporate successors, but
* under section 55 of the Copyright Designs and Patents Act 1988 that
* copyright is no longer infringed by the production or use of
* articles specifically designed or adapted for producing material in
* that typeface.
*
* The rest of the glyphs, and all of the code in this file, were
* written by Ben Harris <bjh21@bjh21.me.uk> and Simon Tatham
* <anakin@pobox.com> between 2009 and 2017.
*
* To the extent possible under law, Ben Harris and Simon Tatham have
* dedicated all copyright and related and neighboring rights to this
* software and the embodied typeface to the public domain worldwide.
* This software and typeface are distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
/*
* This is a program to construct an outline font from a bitmap. It's
* based on the character-rounding algorithm of the Mullard SAA5050
* series of Teletext character generators, and thus works best on
* character shapes in the same style of those of the SAA5050. This
* file includes all of the glyphs from the SAA5050, SAA5051, SAA5052,
* SAA5053, SAA5054, SAA5055, SAA5056, and SAA5057. The output is a
* Spline Font Database file suitable for feeding to Fontforge.
*
* The character-smoothing algorithm of the SAA5050 and friends is
* a fairly simple means of expanding a 5x9 pixel character to 10x18
* pixels for use on an interlaced display. All it does is to detect
* 2x2 clumps of pixels containing a diagonal line and add a couple of
* subpixels to it, like this:
*
* . # -> . . # # -> . . # # or # . -> # # . . -> # # . .
* # . . . # # . # # # . # # # . . # # # .
* # # . . # # # . . . # # . # # #
* # # . . # # . . . . # # . . # #
*
* This is applied to every occurrence of these patterns, even when
* they overlap, and the result is that thin diagonal lines are
* smoothed out while other features mostly remain the same.
*
* One way of extending this towards continuity would be to repeatedly
* double the resolution and add more pixels to diagonals each time,
* but this ends up with the diagonals being much too heavy. Instead,
* in places where the SAA5050 would add pixels, this program adds a
* largeish triangle to each unfilled pixel, and removes a small
* triangle from each filled one, something like this:
*
* . # -> . . # # -> . . / # or # . -> # # . . -> # \ . .
* # . . . # # . / # / . # # # . . \ # \ .
* # # . . / # / . . . # # . \ # \
* # # . . # / . . . . # # . . \ #
*
* The position of the lines is such that on a long diagonal line, the
* amount of filled space is the same as in the rounded bitmap. There
* are a few additional complications, in that the trimming of filled
* pixels can leave odd gaps where a diagonal stem joins another one,
* so the code detects this and doesn't trim in these cases:
*
* . # # -> . . # # # # -> . . / # # # -> . . / # # #
* # . . . . # # # # . / # / # # . / # # # #
* # # . . . . / # / . . . / # / . . .
* # # . . . . # / . . . . # / . . . .
*
* That is the interesting part of the program, and is in the dochar()
* function. Most of the rest is just dull geometry to join all the
* bits together into a sensible outline. Much of the code is wildly
* inefficient -- O(n^2) algorithms aren't much of a problem when you
* have at most a few thousand points to deal with.
*
* A rather nice feature of the outlines produced by this program is
* that when rasterised at precisely 10 or 20 pixels high, they
* produce the input and output respectively of the character-rounding
* process. While there are obious additional smoothings that could
* be applied, doing so would probably lose this nice property.
*
* The glyph bitmaps included below include all the ones from the various
* members of the SAA5050 family that I know about. They are as shown
* in the datasheet, and the English ones have been checked against a
* real SAA5050. Occasionally, different languages have different
* glyphs for the same character -- these are represented as
* alternates, with the default being the glyph that looks best.
*
* There are some extra glyphs included as well, some derived from
* standard ones and some made from whole cloth. They are built on
* the same 5x9 matrix as the originals, and processed in the same way.
*/
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define XSIZE 6
#define YSIZE 10
/*
* Design parameters. These can vary between fonts in the Bedstead family.
*
* To faithfully represent the output of an SAA5050, we need to know a
* little about TV pixel aspect ratios:
*
* http://www.lurkertech.com/lg/video-systems/#sqnonsq
*
* The SAA5050 can be used to drive both 480i ("NTSC") and 576i
* ("PAL") displays. In 480i, industry convention is that you get
* square pixels with a pixel clock of 12+3/11 MHz. In 576i, you need
* 14.75 MHz. The SAA5050 takes a nominal 6MHz clock and uses both
* edges to output subpixels (duty cycle between 0.4 and 0.6). This
* means that the nominal pixel aspect ratios are 12+3/11:12 for 480i
* and 14.75:12 for 576i. These correspond to pixel widths of 102.3
* and 122.9 respectively.
*
* 102.3 is close enough to 100 that we may as well just use square
* pixels, which will work better on modern displays. We round 122.9
* to 124 so that XQTR will be precisely an integer.
*/
struct param {
char const * fontname;
char const * fullname;
int xpix;
int ttfwidth;
};
struct param default_param = {
"Bedstead", "Bedstead",
100, /* xpix */
5, /* ttfwidth */
};
struct param extended_param = {
"Bedstead-Extended", "Bedstead Extended",
124, /* xpix */
7, /* ttfwidth */
};
struct param condensed_param = {
"Bedstead-Condensed", "Bedstead Condensed",
50, /* xpix */
1, /* ttfwidth */
};
struct param semicondensed_param = {
"Bedstead-Semicondensed", "Bedstead Semicondensed",
62, /* xpix */
2, /* ttfwidth */
};
struct param *param = &default_param;
/* Size of pixels in font design units (usually 1000/em) */
#define XPIX (param->xpix)
#define YPIX 100
/* We work internally in smaller units, though. */
#define SCALE 2
#define XPIX_S (XPIX * SCALE)
#define YPIX_S (YPIX * SCALE)
/* Position of diagonal lines within pixels */
#define XQTR_S (XPIX_S/4)
#define YQTR_S (YPIX_S/4)
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];
int unicode;
char const *name;
unsigned int flags;
#define SC 0x01 /* Character has a small-caps variant. */
#define MOS 0x02 /* Mosaic graphics character */
} const glyphs[] = {
/*
* The first batch of glyphs comes from the code tables at the end of
* the Mullard SAA5050 series datasheet, dated July 1982.
*/
/* US ASCII (SAA5055) character set */
{{000,000,000,000,000,000,000,000,000}, 0x0020, "space" },
{{004,004,004,004,004,000,004,000,000}, 0x0021, "exclam" },
{{012,012,012,000,000,000,000,000,000}, 0x0022, "quotedbl" },
{{012,012,037,012,037,012,012,000,000}, 0x0023, "numbersign" },
{{016,025,024,016,005,025,016,000,000}, 0x0024, "dollar" },
{{030,031,002,004,010,023,003,000,000}, 0x0025, "percent" },
{{010,024,024,010,025,022,015,000,000}, 0x0026, "ampersand" },
{{004,004,010,000,000,000,000,000,000}, 0x2019, "quoteright" },
{{002,004,010,010,010,004,002,000,000}, 0x0028, "parenleft" },
{{010,004,002,002,002,004,010,000,000}, 0x0029, "parenright" },
{{004,025,016,004,016,025,004,000,000}, 0x002a, "asterisk" },
{{000,004,004,037,004,004,000,000,000}, 0x002b, "plus" },
{{000,000,000,000,000,004,004,010,000}, 0x002c, "comma"},
{{000,000,000,016,000,000,000,000,000}, 0x002d, "hyphen" },
{{000,000,000,000,000,000,004,000,000}, 0x002e, "period"},
{{000,001,002,004,010,020,000,000,000}, 0x002f, "slash" },
{{004,012,021,021,021,012,004,000,000}, 0x0030, "zero" },
{{004,014,004,004,004,004,016,000,000}, 0x0031, "one" },
{{016,021,001,006,010,020,037,000,000}, 0x0032, "two" },
{{037,001,002,006,001,021,016,000,000}, 0x0033, "three" },
{{002,006,012,022,037,002,002,000,000}, 0x0034, "four" },
{{037,020,036,001,001,021,016,000,000}, 0x0035, "five" },
{{006,010,020,036,021,021,016,000,000}, 0x0036, "six" },
{{037,001,002,004,010,010,010,000,000}, 0x0037, "seven" },
{{016,021,021,016,021,021,016,000,000}, 0x0038, "eight" },
{{016,021,021,017,001,002,014,000,000}, 0x0039, "nine" },
{{000,000,004,000,000,000,004,000,000}, 0x003a, "colon"},
{{000,000,004,000,000,004,004,010,000}, 0x003b, "semicolon"},
{{002,004,010,020,010,004,002,000,000}, 0x003c, "less" },
{{000,000,037,000,037,000,000,000,000}, 0x003d, "equal" },
{{010,004,002,001,002,004,010,000,000}, 0x003e, "greater" },
{{016,021,002,004,004,000,004,000,000}, 0x003f, "question" },
{{016,021,027,025,027,020,016,000,000}, 0x0040, "at" },
{{004,012,021,021,037,021,021,000,000}, 0x0041, "A", SC },
{{036,021,021,036,021,021,036,000,000}, 0x0042, "B", SC },
{{016,021,020,020,020,021,016,000,000}, 0x0043, "C", SC },
{{036,021,021,021,021,021,036,000,000}, 0x0044, "D", SC },
{{037,020,020,036,020,020,037,000,000}, 0x0045, "E", SC },
{{037,020,020,036,020,020,020,000,000}, 0x0046, "F", SC },
{{016,021,020,020,023,021,017,000,000}, 0x0047, "G", SC },
{{021,021,021,037,021,021,021,000,000}, 0x0048, "H", SC },
{{016,004,004,004,004,004,016,000,000}, 0x0049, "I", SC },
{{001,001,001,001,001,021,016,000,000}, 0x004a, "J", SC },
{{021,022,024,030,024,022,021,000,000}, 0x004b, "K", SC },
{{020,020,020,020,020,020,037,000,000}, 0x004c, "L", SC },
{{021,033,025,025,021,021,021,000,000}, 0x004d, "M", SC },
{{021,021,031,025,023,021,021,000,000}, 0x004e, "N", SC },
{{016,021,021,021,021,021,016,000,000}, 0x004f, "O", SC },
{{036,021,021,036,020,020,020,000,000}, 0x0050, "P", SC },
{{016,021,021,021,025,022,015,000,000}, 0x0051, "Q", SC },
{{036,021,021,036,024,022,021,000,000}, 0x0052, "R", SC },
{{016,021,020,016,001,021,016,000,000}, 0x0053, "S", SC },
{{037,004,004,004,004,004,004,000,000}, 0x0054, "T", SC },
{{021,021,021,021,021,021,016,000,000}, 0x0055, "U", SC },
{{021,021,021,012,012,004,004,000,000}, 0x0056, "V", SC },
{{021,021,021,025,025,025,012,000,000}, 0x0057, "W", SC },
{{021,021,012,004,012,021,021,000,000}, 0x0058, "X", SC },
{{021,021,012,004,004,004,004,000,000}, 0x0059, "Y", SC },
{{037,001,002,004,010,020,037,000,000}, 0x005a, "Z", SC },
{{017,010,010,010,010,010,017,000,000}, 0x005b, "bracketleft" },
{{000,020,010,004,002,001,000,000,000}, 0x005c, "backslash" },
{{036,002,002,002,002,002,036,000,000}, 0x005d, "bracketright" },
{{004,012,021,000,000,000,000,000,000}, 0x005e, "asciicircum" },
{{000,000,000,000,000,000,037,000,000}, 0x005f, "underscore" },
{{004,004,002,000,000,000,000,000,000}, 0x201b, "quotereversed" },
{{000,000,016,001,017,021,017,000,000}, 0x0061, "a", SC },
{{020,020,036,021,021,021,036,000,000}, 0x0062, "b", SC },
{{000,000,017,020,020,020,017,000,000}, 0x0063, "c", SC },
{{001,001,017,021,021,021,017,000,000}, 0x0064, "d", SC },
{{000,000,016,021,037,020,016,000,000}, 0x0065, "e", SC },
{{002,004,004,016,004,004,004,000,000}, 0x0066, "f", SC },
{{000,000,017,021,021,021,017,001,016}, 0x0067, "g", SC },
{{020,020,036,021,021,021,021,000,000}, 0x0068, "h", SC },
{{004,000,014,004,004,004,016,000,000}, 0x0069, "i", SC },
{{004,000,004,004,004,004,004,004,010}, 0x006a, "j", SC },
{{010,010,011,012,014,012,011,000,000}, 0x006b, "k", SC },
{{014,004,004,004,004,004,016,000,000}, 0x006c, "l", SC },
{{000,000,032,025,025,025,025,000,000}, 0x006d, "m", SC },
{{000,000,036,021,021,021,021,000,000}, 0x006e, "n", SC },
{{000,000,016,021,021,021,016,000,000}, 0x006f, "o", SC },
{{000,000,036,021,021,021,036,020,020}, 0x0070, "p", SC },
{{000,000,017,021,021,021,017,001,001}, 0x0071, "q", SC },
{{000,000,013,014,010,010,010,000,000}, 0x0072, "r", SC },
{{000,000,017,020,016,001,036,000,000}, 0x0073, "s", SC },
{{004,004,016,004,004,004,002,000,000}, 0x0074, "t", SC },
{{000,000,021,021,021,021,017,000,000}, 0x0075, "u", SC },
{{000,000,021,021,012,012,004,000,000}, 0x0076, "v", SC },
{{000,000,021,021,025,025,012,000,000}, 0x0077, "w", SC },
{{000,000,021,012,004,012,021,000,000}, 0x0078, "x", SC },
{{000,000,021,021,021,021,017,001,016}, 0x0079, "y", SC },
{{000,000,037,002,004,010,037,000,000}, 0x007a, "z", SC },
{{003,004,004,010,004,004,003,000,000}, 0x007b, "braceleft" },
{{004,004,004,000,004,004,004,000,000}, 0x00a6, "brokenbar" },
{{030,004,004,002,004,004,030,000,000}, 0x007d, "braceright" },
{{010,025,002,000,000,000,000,000,000}, 0x007e, "asciitilde" },
{{037,037,037,037,037,037,037,000,000}, 0x25a0, "filledbox" },
/* Extra characters found in the English (SAA5050) character set */
{{006,011,010,034,010,010,037,000,000}, 0x00a3, "sterling" },
{{004,004,004,000,000,000,000,000,000}, 0x0027, "quotesingle" },
{{000,004,010,037,010,004,000,000,000}, 0x2190, "arrowleft" },
{{020,020,020,020,026,001,002,004,007}, 0x00bd, "onehalf" },
{{000,004,002,037,002,004,000,000,000}, 0x2192, "arrowright" },
{{000,004,016,025,004,004,000,000,000}, 0x2191, "arrowup" },
{{000,000,000,037,000,000,000,000,000}, 0x2014, "emdash" },
{{010,010,010,010,011,003,005,007,001}, 0x00bc, "onequarter" },
{{012,012,012,012,012,012,012,000,000}, 0x2016, "dblverticalbar" },
{{030,004,030,004,031,003,005,007,001}, 0x00be, "threequarters" },
{{000,004,000,037,000,004,000,000,000}, 0x00f7, "divide" },
/* Extra characters found in the German (SAA5051) character set */
{{000,000,000,000,000,010,010,020,000}, -1, "comma.saa5051" },
{{000,000,000,000,000,014,014,000,000}, -1, "period.saa5051" },
{{000,000,000,010,000,000,010,000,000}, -1, "colon.saa5051" },
{{000,000,010,000,000,010,010,020,000}, -1, "semicolon.saa5051" },
{{016,021,020,016,021,016,001,021,016}, 0x00a7, "section" },
{{012,000,016,021,037,021,021,000,000}, 0x00c4, "Adieresis" },
{{012,000,016,021,021,021,016,000,000}, 0x00d6, "Odieresis" },
{{012,000,021,021,021,021,016,000,000}, 0x00dc, "Udieresis" },
{{006,011,006,000,000,000,000,000,000}, 0x00b0, "degree" },
{{012,000,016,001,017,021,017,000,000}, 0x00e4, "adieresis" },
{{000,012,000,016,021,021,016,000,000}, 0x00f6, "odieresis" },
{{000,012,000,021,021,021,017,000,000}, 0x00fc, "udieresis" },
{{014,022,022,026,021,021,026,020,020}, 0x00df, "germandbls" },
/* Extra characters found in the Swedish (SAA5052) character set */
{{000,000,021,016,012,016,021,000,000}, 0x00a4, "currency" },
{{002,004,037,020,036,020,037,000,000}, 0x00c9, "Eacute" },
{{016,011,011,011,011,011,016,000,000}, -1, "D.saa5052", SC },
{{010,010,010,010,010,010,017,000,000}, -1, "L.saa5052", SC },
{{004,000,016,021,037,021,021,000,000}, 0x00c5, "Aring" },
{{002,004,016,021,037,020,016,000,000}, 0x00e9, "eacute" },
{{004,000,016,001,017,021,017,000,000}, 0x00e5, "aring" },
/* Extra characters found in the Italian (SAA5053) character set */
{{000,000,017,020,020,020,017,002,004}, 0x00e7, "ccedilla" },
{{010,004,021,021,021,021,017,000,000}, 0x00f9, "ugrave" },
{{010,004,016,001,017,021,017,000,000}, 0x00e0, "agrave" },
{{010,004,000,016,021,021,016,000,000}, 0x00f2, "ograve" },
{{010,004,016,021,037,020,016,000,000}, 0x00e8, "egrave" },
{{010,004,000,014,004,004,016,000,000}, 0x00ec, "igrave" },
/* Extra characters found in the Belgian (SAA5054) character set */
{{012,000,014,004,004,004,016,000,000}, 0x00ef, "idieresis" },
{{012,000,016,021,037,020,016,000,000}, 0x00eb, "edieresis" },
{{004,012,016,021,037,020,016,000,000}, 0x00ea, "ecircumflex" },
{{004,002,021,021,021,021,017,000,000}, -1, "ugrave.saa5054" },
{{004,012,000,014,004,004,016,000,000}, 0x00ee, "icircumflex" },
{{004,012,016,001,017,021,017,000,000}, 0x00e2, "acircumflex" },
{{004,012,016,021,021,021,016,000,000}, -1, "ocircumflex.saa5054" },
{{004,012,000,021,021,021,017,000,000}, 0x00fb, "ucircumflex" },
{{000,000,017,020,020,020,017,002,006}, -1, "ccedilla.saa5054" },
/* Extra characters found in the Hebrew (SAA5056) character set */
{{000,021,011,025,022,021,021,000,000}, 0x05d0 }, /* alef */
{{000,016,002,002,002,002,037,000,000}, 0x05d1 }, /* bet */
{{000,003,001,001,003,005,011,000,000}, 0x05d2 }, /* gimel */
{{000,037,002,002,002,002,002,000,000}, 0x05d3 }, /* dalet */
{{000,037,001,001,021,021,021,000,000}, 0x05d4 }, /* he */
{{000,014,004,004,004,004,004,000,000}, 0x05d5 }, /* vav */
{{000,016,004,010,004,004,004,000,000}, 0x05d6 }, /* zayin */
{{000,037,021,021,021,021,021,000,000}, 0x05d7 }, /* het */
{{000,021,023,025,021,021,037,000,000}, 0x05d8 }, /* tet */
{{000,014,004,000,000,000,000,000,000}, 0x05d9 }, /* yod */
{{000,037,001,001,001,001,001,001,000}, 0x05da }, /* kaffinal */
{{000,037,001,001,001,001,037,000,000}, 0x05db }, /* kaf */
{{020,037,001,001,001,002,014,000,000}, 0x05dc }, /* lamed */
{{000,037,021,021,021,021,037,000,000}, 0x05dd }, /* memfinal */
{{000,026,011,021,021,021,027,000,000}, 0x05de }, /* mem */
{{000,014,004,004,004,004,004,004,004}, 0x05df }, /* nunfinal */
{{000,006,002,002,002,002,016,000,000}, 0x05e0 }, /* nun */
{{000,037,011,021,021,021,016,000,000}, 0x05e1 }, /* samekh */
{{000,011,011,011,011,012,034,000,000}, 0x05e2 }, /* ayin */
{{000,037,011,015,001,001,001,001,000}, 0x05e3 }, /* pefinal */
{{000,037,011,015,001,001,037,000,000}, 0x05e4 }, /* pe */
{{000,031,012,014,010,010,010,010,000}, 0x05e5 }, /* tsadifinal */
{{000,021,021,012,004,002,037,000,000}, 0x05e6 }, /* tsadi */
{{000,037,001,011,011,012,010,010,000}, 0x05e7 }, /* qof */
{{000,037,001,001,001,001,001,000,000}, 0x05e8 }, /* resh */
{{000,025,025,025,031,021,036,000,000}, 0x05e9 }, /* shin */
{{000,017,011,011,011,011,031,000,000}, 0x05ea }, /* tav */
{{000,000,025,025,016,000,000,000,000}, -1, "oldsheqel" },
/* Extra characters found in the Cyrillic (SAA5057) character set */
{{000,000,021,021,035,025,035,000,000}, 0x044b }, /* yeru */
{{022,025,025,035,025,025,022,000,000}, 0x042e }, /* Iu */
{{016,021,021,021,037,021,021,000,000}, 0x0410 }, /* A */
{{037,020,020,037,021,021,037,000,000}, 0x0411 }, /* Be */
{{022,022,022,022,022,022,037,001,000}, 0x0426 }, /* Tse */
{{006,012,012,012,012,012,037,021,000}, 0x0414 }, /* De */
{{037,020,020,036,020,020,037,000,000}, 0x0415 }, /* Ie */
{{004,037,025,025,025,037,004,000,000}, 0x0424 }, /* Ef */
{{037,020,020,020,020,020,020,000,000}, 0x0413 }, /* Ghe */
{{021,021,012,004,012,021,021,000,000}, 0x0425 }, /* Ha */
{{021,021,023,025,031,021,021,000,000}, 0x0418 }, /* I */
{{025,021,023,025,031,021,021,000,000}, 0x0419 }, /* Ishort */
{{021,022,024,030,024,022,021,000,000}, 0x041a }, /* Ka */
{{007,011,011,011,011,011,031,000,000}, 0x041b }, /* El */
{{021,033,025,025,021,021,021,000,000}, 0x041c }, /* Em */
{{021,021,021,037,021,021,021,000,000}, 0x041d }, /* En */
{{016,021,021,021,021,021,016,000,000}, 0x041e }, /* O */
{{037,021,021,021,021,021,021,000,000}, 0x041f }, /* Pe */
{{017,021,021,017,005,011,021,000,000}, 0x042f }, /* Ya */
{{036,021,021,036,020,020,020,000,000}, 0x0420 }, /* Er */
{{016,021,020,020,020,021,016,000,000}, 0x0421 }, /* Es */
{{037,004,004,004,004,004,004,000,000}, 0x0422 }, /* Te */
{{021,021,021,037,001,001,037,000,000}, 0x0423 }, /* U */
{{025,025,025,016,025,025,025,000,000}, 0x0416 }, /* Zhe */
{{036,021,021,036,021,021,036,000,000}, 0x0412 }, /* Ve */
{{020,020,020,037,021,021,037,000,000}, 0x042c }, /* Soft */
{{030,010,010,017,011,011,017,000,000}, 0x042a }, /* Hard */
{{016,021,001,006,001,021,016,000,000}, 0x0417 }, /* Ze */
{{025,025,025,025,025,025,037,000,000}, 0x0428 }, /* Sha */
{{014,022,001,007,001,022,014,000,000}, 0x042d }, /* E */
{{025,025,025,025,025,025,037,001,000}, 0x0429 }, /* Shcha */
{{021,021,021,037,001,001,001,000,000}, 0x0427 }, /* Che */
{{021,021,021,035,025,025,035,000,000}, 0x042b }, /* Yeru */
{{000,000,022,025,035,025,022,000,000}, 0x044e }, /* yu */
{{000,000,016,001,017,021,017,000,000}, 0x0430 }, /* a */
{{016,020,036,021,021,021,036,000,000}, 0x0431 }, /* be */
{{000,000,022,022,022,022,037,001,000}, 0x0446 }, /* tse */
{{000,000,006,012,012,012,037,021,000}, 0x0434 }, /* de */
{{000,000,016,021,037,020,016,000,000}, 0x0435 }, /* ie */
{{000,004,016,025,025,025,016,004,000}, 0x0444 }, /* ef */
{{000,000,037,020,020,020,020,000,000}, 0x0433 }, /* ghe */
{{000,000,021,012,004,012,021,000,000}, 0x0445 }, /* ha */
{{000,000,021,023,025,031,021,000,000}, 0x0438 }, /* i */
{{000,004,021,023,025,031,021,000,000}, 0x0439 }, /* ishort */
{{000,000,021,022,034,022,021,000,000}, 0x043a }, /* ka */
{{000,000,007,011,011,011,031,000,000}, 0x043b }, /* el */
{{000,000,021,033,025,021,021,000,000}, 0x043c }, /* em */
{{000,000,021,021,037,021,021,000,000}, 0x043d }, /* en */
{{000,000,016,021,021,021,016,000,000}, 0x043e }, /* o */
{{000,000,037,021,021,021,021,000,000}, 0x043f }, /* pe */
{{000,000,017,021,017,005,031,000,000}, 0x044f }, /* ya */
{{000,000,036,021,021,021,036,020,020}, 0x0440 }, /* er */
{{000,000,016,021,020,021,016,000,000}, 0x0441 }, /* es */
{{000,000,037,004,004,004,004,000,000}, 0x0442 }, /* te */
{{000,000,021,021,021,021,017,001,016}, 0x0443 }, /* u */
{{000,000,025,025,016,025,025,000,000}, 0x0436 }, /* zhe */
{{000,000,036,021,036,021,036,000,000}, 0x0432 }, /* ve */
{{000,000,020,020,036,021,036,000,000}, 0x044c }, /* soft */
{{000,000,030,010,016,011,016,000,000}, 0x044a }, /* hard */
{{000,000,016,021,006,021,016,000,000}, 0x0437 }, /* ze */
{{000,000,025,025,025,025,037,000,000}, 0x0448 }, /* sha */
{{000,000,014,022,006,022,014,000,000}, 0x044d }, /* e */
{{000,000,025,025,025,025,037,001,000}, 0x0449 }, /* shcha */
{{000,000,021,021,021,017,001,000,000}, 0x0447 }, /* che */
/*
* The other batch of glyphs were specially designed for this font.
* These are kept sorted by Unicode code point.
*/
/* Basic Latin */
{{010,004,002,000,000,000,000,000,000}, 0x0060, "grave" },
{{004,004,004,004,004,004,004,000,000}, 0x007c, "bar" },
/* Latin-1 supplement */
{{000,000,004,000,004,004,004,004,004}, 0x00a1, "exclamdown" },
{{000,004,017,024,024,024,017,004,000}, 0x00a2, "cent" },
{{021,012,037,004,037,004,004,000,000}, 0x00a5, "yen" },
{{022,000,000,000,000,000,000,000,000}, 0x00a8, "dieresis" },
{{016,021,025,033,031,033,025,021,016}, 0x00a9, "copyright" },
{{016,001,017,021,017,000,037,000,000}, 0x00aa, "ordfemenine" },
{{000,000,000,011,022,011,000,000,000}, 0x00ab, "guillemotleft" },
{{000,000,037,001,001,000,000,000,000}, 0x00ac, "logicalnot" },
{{016,021,035,033,033,035,033,021,016}, 0x00ae, "registered" },
{{016,000,000,000,000,000,000,000,000}, 0x00af, "macron" },
{{004,004,037,004,004,000,037,000,000}, 0x00b1, "plusminus" },
{{014,002,004,010,016,000,000,000,000}, 0x00b2, "twosuperior" },
{{014,002,014,002,014,000,000,000,000}, 0x00b3, "threesuperior" },
{{002,004,010,000,000,000,000,000,000}, 0x00b4, "acute" },
{{000,000,022,022,022,022,035,020,020}, 0x00b5, "mu" },
{{015,025,025,015,005,005,005,000,000}, 0x00b6, "paragraph" },
{{000,000,000,004,000,000,000,000,000}, 0x00b7, "periodcentered" },
{{000,000,000,000,000,000,004,002,004}, 0x00b8, "cedilla" },
{{004,014,004,004,016,000,000,000,000}, 0x00b9, "onesuperior" },
{{016,021,021,021,016,000,037,000,000}, 0x00ba, "ordmasculine" },
{{000,000,000,022,011,022,000,000,000}, 0x00bb, "guillemotright" },
{{000,000,004,000,004,004,010,021,016}, 0x00bf, "questiondown" },
{{010,004,016,021,037,021,021,000,000}, 0x00c0, "Agrave" },
{{002,004,016,021,037,021,021,000,000}, 0x00c1, "Aacute" },
{{004,012,016,021,037,021,021,000,000}, 0x00c2, "Acircumflex" },
{{005,012,016,021,037,021,021,000,000}, 0x00c3, "Atilde" },
{{017,024,024,036,024,024,027,000,000}, 0x00c6, "AE" },
{{016,021,020,020,020,021,016,004,010}, 0x00c7, "Ccedilla" },
{{010,004,037,020,036,020,037,000,000}, 0x00c8, "Egrave" },
{{004,012,037,020,036,020,037,000,000}, 0x00ca, "Ecircumflex" },
{{012,000,037,020,036,020,037,000,000}, 0x00cb, "Edieresis" },
{{010,004,000,016,004,004,016,000,000}, 0x00cc, "Igrave" },
{{002,004,000,016,004,004,016,000,000}, 0x00cd, "Iacute" },
{{004,012,000,016,004,004,016,000,000}, 0x00ce, "Icircumflex" },
{{012,000,016,004,004,004,016,000,000}, 0x00cf, "Idieresis" },
{{016,011,011,035,011,011,016,000,000}, 0x00d0, "Eth" },
{{005,012,000,031,025,023,021,000,000}, 0x00d1, "Ntilde" },
{{010,004,016,021,021,021,016,000,000}, 0x00d2, "Ograve" },
{{002,004,016,021,021,021,016,000,000}, 0x00d3, "Oacute" },
{{004,012,016,021,021,021,016,000,000}, 0x00d4, "Ocircumflex" },
{{005,012,016,021,021,021,016,000,000}, 0x00d5, "Otilde" },
{{000,021,012,004,012,021,000,000,000}, 0x00d7, "multiply" },
{{016,021,023,025,031,021,016,000,000}, 0x00d8, "Oslash" },
{{010,004,021,021,021,021,016,000,000}, 0x00d9, "Ugrave" },
{{002,004,021,021,021,021,016,000,000}, 0x00da, "Uacute" },
{{004,012,000,021,021,021,016,000,000}, 0x00db, "Ucircumflex" },
{{002,004,021,012,004,004,004,000,000}, 0x00dd, "Yacute" },
{{020,036,021,021,036,020,020,000,000}, 0x00de, "Thorn" },
{{002,004,016,001,017,021,017,000,000}, 0x00e1, "aacute" },
{{005,012,016,001,017,021,017,000,000}, 0x00e3, "atilde" },
{{000,000,012,005,017,024,016,000,000}, 0x00e6, "ae" },
{{002,004,000,014,004,004,016,000,000}, 0x00ed, "iacute" },
{{032,004,012,001,017,021,016,000,000}, 0x00f0, "eth" },
{{005,012,036,021,021,021,021,000,000}, 0x00f1, "ntilde" },
{{002,004,000,016,021,021,016,000,000}, 0x00f3, "oacute" },
{{004,012,000,016,021,021,016,000,000}, 0x00f4, "ocircumflex" },
{{005,012,000,016,021,021,016,000,000}, 0x00f5, "otilde" },
{{000,000,017,023,025,031,036,000,000}, 0x00f8, "oslash" },
{{002,004,021,021,021,021,017,000,000}, 0x00fa, "uacute" },
{{002,004,021,021,021,021,017,001,016}, 0x00fd, "yacute" },
{{020,020,036,021,021,021,036,020,020}, 0x00fe, "thorn" },
{{012,000,021,021,021,021,017,001,016}, 0x00ff, "ydieresis" },
/* Latin extended-A */
{{016,000,016,021,037,021,021,000,000}, 0x0100, "Amacron" },
{{016,000,016,001,017,021,017,000,000}, 0x0101, "amacron" },
{{002,004,016,021,020,021,016,000,000}, 0x0106, "Cacute" },
{{002,004,017,020,020,020,017,000,000}, 0x0107, "cacute" },
{{004,012,016,021,020,021,016,000,000}, 0x0108, "Ccircumflex" },
{{004,012,017,020,020,020,017,000,000}, 0x0109, "ccircumflex" },
{{004,000,016,021,020,021,016,000,000}, 0x010a, "Cdotaccent" },
{{004,000,017,020,020,020,017,000,000}, 0x010b, "cdotaccent" },
{{012,004,016,021,020,021,016,000,000}, 0x010c, "Ccaron" },
{{012,004,017,020,020,020,017,000,000}, 0x010d, "ccaron" },
{{012,004,036,021,021,021,036,000,000}, 0x010e, "Dcaron" },
{{005,005,014,024,024,024,014,000,000}, 0x010f, "dcaron" },
{{016,011,011,035,011,011,016,000,000}, 0x0110, "Dcroat" },
{{002,007,002,016,022,022,016,000,000}, 0x0111, "dcroat" },
{{016,000,037,020,036,020,037,000,000}, 0x0112, "Emacron" },
{{016,000,016,021,037,020,016,000,000}, 0x0113, "emacron" },
{{004,000,037,020,036,020,037,000,000}, 0x0116, "Edotaccent" },
{{004,000,016,021,037,020,016,000,000}, 0x0117, "edotaccent" },
{{012,004,037,020,036,020,037,000,000}, 0x011a, "Ecaron" },
{{012,004,016,021,037,020,016,000,000}, 0x011b, "ecaron" },
{{004,012,017,020,023,021,017,000,000}, 0x011c, "Gcircumflex" },
{{004,012,017,021,021,021,017,001,016}, 0x011d, "gcircumflex" },
{{004,000,017,020,023,021,017,000,000}, 0x0120, "Gdotaccent" },
{{004,000,017,021,021,021,017,001,016}, 0x0121, "gdotaccent" },
{{021,037,021,037,021,021,021,000,000}, 0x0126, "Hbar" },
{{010,034,010,016,011,011,011,000,000}, 0x0127, "hbar" },
{{016,000,016,004,004,004,016,000,000}, 0x012a, "Imacron" },
{{016,000,014,004,004,004,016,000,000}, 0x012b, "imacron" },
{{004,000,016,004,004,004,016,000,000}, 0x0130, "Idotaccent" },
{{000,000,014,004,004,004,016,000,000}, 0x0131, "dotlessi" },
{{021,021,021,021,021,025,022,000,000}, 0x0132, "IJ" },
{{011,000,031,011,011,011,035,001,002}, 0x0133, "ij" },
{{000,000,021,022,034,022,021,000,000}, 0x0138, "kgreenlandic" },
{{020,020,020,021,020,020,037,000,000}, 0x013f, "Ldot" },
{{030,010,010,011,010,010,034,000,000}, 0x0140, "ldot" },
{{012,004,021,031,025,023,021,000,000}, 0x0147, "Ncaron" },
{{012,004,036,021,021,021,021,000,000}, 0x0148, "ncaron" },
{{021,021,031,025,023,021,021,001,016}, 0x014a, "Eng" },
{{000,000,036,021,021,021,021,001,016}, 0x014b, "eng" },
{{016,000,016,021,021,021,016,000,000}, 0x014c, "Omacron" },
{{000,016,000,016,021,021,016,000,000}, 0x014d, "omacron" },
{{017,024,024,026,024,024,017,000,000}, 0x0152, "OE" },
{{000,000,012,025,027,024,013,000,000}, 0x0153, "oe" },
{{012,004,036,021,036,022,021,000,000}, 0x0158, "Rcaron" },
{{005,002,013,014,010,010,010,000,000}, 0x0159, "rcaron" },
{{012,004,017,020,016,001,036,000,000}, 0x0161, "scaron" },
{{012,004,037,004,004,004,004,000,000}, 0x0164, "Tcaron" },
{{011,011,034,010,010,010,004,000,000}, 0x0165, "tcaron" },
{{004,000,021,021,021,021,016,000,000}, 0x016e, "Uring" },
{{004,000,021,021,021,021,017,000,000}, 0x016f, "uring" },
{{016,000,021,021,021,021,016,000,000}, 0x016a, "Umacron" },
{{000,016,000,021,021,021,017,000,000}, 0x016b, "umacron" },
{{004,012,000,021,012,004,004,000,000}, 0x0176, "Ycircumflex" },
{{004,012,000,021,021,021,017,001,016}, 0x0177, "ycircumflex" },
{{012,000,021,012,004,004,004,000,000}, 0x0178, "Ydieresis" },
{{002,004,037,001,016,020,037,000,000}, 0x0179, "Zacute" },
{{002,004,037,002,004,010,037,000,000}, 0x017a, "zacute" },
{{004,000,037,001,016,020,037,000,000}, 0x017b, "Zdotaccent" },
{{004,000,037,002,004,010,037,000,000}, 0x017c, "zdotaccent" },
{{012,004,037,001,016,020,037,000,000}, 0x017d, "Zcaron" },
{{012,004,037,002,004,010,037,000,000}, 0x017e, "zcaron" },
/* Latin extended-B */
{{003,002,017,020,020,020,017,000,000}, 0x0188 }, /* Hooktop C */
{{002,004,004,016,004,004,004,004,010}, 0x0192, "florin" },
{{006,010,011,012,014,012,011,000,000}, 0x0199 }, /* Hooktop K */
{{030,004,016,004,012,012,021,000,000}, 0x019b }, /* Barred lambda */
{{000,000,036,021,021,021,021,001,001}, 0x019e }, /* N, right leg */
{{014,020,036,021,021,021,036,020,020}, 0x01a5 }, /* Hooktop P */
{{004,004,016,004,004,006,001,006,000}, 0x01ab }, /* Left-hook T */
{{002,004,016,004,004,004,002,000,000}, 0x01ad }, /* Hooktop T */
{{016,021,005,002,015,020,037,000,000}, 0x01bb }, /* Barred two */
{{004,004,004,004,004,004,004,004,004}, 0x01c0 }, /* Pipe */
{{012,012,012,012,012,012,012,012,012}, 0x01c1 }, /* Double pipe */
{{004,004,004,037,004,037,004,004,004}, 0x01c2 }, /* Double-barred pipe */
{{004,004,004,004,004,000,004,000,000}, 0x01c3 }, /* Exclamation point */
{{012,004,000,004,004,004,004,004,010}, 0x01f0 }, /* J wedge */
/* IPA Extensions */
{{000,000,036,021,036,020,016,000,000}, 0x0250 }, /* Turned A */
{{000,000,017,021,021,023,015,000,000}, 0x0251 }, /* Script A */
{{000,000,026,031,021,021,036,000,000}, 0x0252 }, /* Turned script A */
{{014,020,036,021,021,021,036,000,000}, 0x0253 }, /* Hooktop B */
{{000,000,036,001,001,001,036,000,000}, 0x0254 }, /* Open O */
{{000,000,017,020,022,025,016,004,000}, 0x0255 }, /* Curly-tail C */
{{002,002,016,022,022,022,016,002,001}, 0x0256 }, /* Right-tail D */
{{001,002,016,022,022,022,016,000,000}, 0x0257 }, /* Hooktop D */
{{000,000,016,021,037,001,016,000,000}, 0x0258 }, /* Reversed E */
{{000,000,016,001,037,021,016,000,000}, 0x0259 }, /* Schwa */
{{000,000,030,004,035,026,010,000,000}, 0x025a }, /* Right-hook schwa */
{{000,000,017,020,016,020,017,000,000}, 0x025b }, /* Epsilon */
{{000,000,036,001,016,001,036,000,000}, 0x025c }, /* Reversed epsilon */
{{000,000,030,004,031,060,030,000,000}, 0x025d }, /* Right-hook rev epsilon */
{{000,000,016,021,026,021,016,000,000}, 0x025e }, /* Closed reversed epsilon */
{{000,000,004,004,016,004,004,004,010}, 0x025f }, /* Barred dotless J */
{{001,002,016,022,022,022,016,002,014}, 0x0260 }, /* Hooktop G */
{{000,000,017,021,021,021,017,001,016}, 0x0261 }, /* Opentail G */
{{000,000,017,020,023,021,017,000,000}, 0x0262 }, /* Small capital G */
{{000,000,021,012,012,004,012,012,004}, 0x0263 }, /* Gamma */
{{000,000,033,004,012,012,004,000,000}, 0x0264 }, /* Ram's horns */
{{000,000,021,021,021,021,017,001,001}, 0x0265 }, /* Turned H */
{{014,020,036,021,021,021,021,000,000}, 0x0266 }, /* Hooktop H */
{{014,020,036,021,021,021,021,001,006}, 0x0267 }, /* Hooktop heng */
{{004,000,014,004,016,004,016,000,000}, 0x0268 }, /* Barred I */
{{000,000,014,004,004,004,002,000,000}, 0x0269 }, /* Iota */
{{000,000,016,004,004,004,016,000,000}, 0x026a }, /* Small capital I */
{{014,004,015,026,004,004,016,000,000}, 0x026b }, /* L with tilde */
{{014,004,014,025,016,004,016,000,000}, 0x026c }, /* Belted L */
{{014,004,004,004,004,004,004,004,002}, 0x026d }, /* Right-tail L */
{{030,010,017,011,012,011,035,001,006}, 0x026e }, /* L-Ezh ligature */
{{000,000,025,025,025,025,013,000,000}, 0x026f }, /* Turned M */
{{000,000,025,025,025,025,013,001,001}, 0x0270 }, /* Turned M, right tail */
{{000,000,032,025,025,025,025,001,002}, 0x0271 }, /* Left-tail M (at right) */
{{000,000,016,011,011,011,011,010,020}, 0x0272 }, /* Left-tail N (at left) */
{{000,000,034,022,022,022,022,002,001}, 0x0273 }, /* Right-tail N */
{{000,000,021,031,025,023,021,000,000}, 0x0274 }, /* Small capital N */
{{000,000,016,021,037,021,016,000,000}, 0x0275 }, /* Barred O */
{{000,000,017,024,027,024,017,000,000}, 0x0276 }, /* Small capital O-E ligature */
{{000,000,016,021,025,025,012,000,000}, 0x0277 }, /* Closed omega */
{{004,004,016,025,025,025,016,004,004}, 0x0278 }, /* Phi */
{{000,000,002,002,002,006,032,000,000}, 0x0279 }, /* Turned R */
{{002,002,002,002,002,006,032,000,000}, 0x027a }, /* Turned long-leg R */
{{000,000,002,002,002,006,032,002,001}, 0x027b }, /* Turned R, rigfht tail */
{{000,000,013,014,010,010,010,010,010}, 0x027c }, /* Long-leg R */
{{000,000,013,014,010,010,010,010,004}, 0x027d }, /* Right-tail R */
{{000,000,006,011,010,010,010,000,000}, 0x027e }, /* Fish-hook R */
{{000,000,036,021,036,022,021,000,000}, 0x0280 }, /* Small capital R */
{{000,000,021,022,036,021,036,000,000}, 0x0281 }, /* Inverted small capital R */
{{000,000,017,020,016,001,036,020,010}, 0x0282 }, /* Right-tail S (at left) */
{{002,004,004,004,004,004,004,004,010}, 0x0283 }, /* Esh */
{{002,004,004,004,016,004,004,004,010}, 0x0284 }, /* Hooktop barred dotless J */
{{002,004,004,004,004,016,024,024,010}, 0x0286 }, /* Curly-tail esh */
{{000,000,010,004,004,004,016,004,004}, 0x0287 }, /* Turned T */
{{004,004,016,004,004,004,004,004,002}, 0x0288 }, /* Right-tail T */
{{000,000,012,037,012,012,006,000,000}, 0x0289 }, /* Barred U */
{{000,000,033,012,021,021,016,000,000}, 0x028a }, /* Upsilon */
{{000,000,032,011,011,012,014,000,000}, 0x028b }, /* Cursive V */
{{000,000,004,012,012,021,021,000,000}, 0x028c }, /* Turned V */
{{000,000,012,025,025,021,021,000,000}, 0x028d }, /* Turned W */
{{016,020,036,021,021,021,021,000,000}, 0x028e }, /* Turned Y */
{{000,000,021,012,004,004,004,000,000}, 0x028f }, /* Small capital Y */
{{000,000,036,004,010,020,036,002,001}, 0x0290 }, /* Right-tail Z */
{{000,000,037,002,004,010,036,005,002}, 0x0291 }, /* Curly-tail Z */
{{000,000,037,002,004,016,001,021,016}, 0x0292 }, /* Ezh; Tailed Z */
{{000,000,037,002,004,002,011,025,016}, 0x0293 }, /* Curly-tail ezh */
{{016,021,020,020,020,020,020,021,016}, 0x0297 }, /* Stretched C */
{{000,000,036,021,036,021,036,000,000}, 0x0299 }, /* Small capital B */
{{016,021,002,004,004,004,004,000,000}, 0x0294 }, /* Glottal stop */
{{016,021,010,004,004,004,004,000,000}, 0x0295 }, /* Reversed glottal stop */
{{004,004,004,004,002,021,016,000,000}, 0x0296 }, /* Inverted glottal stop */
{{016,021,021,025,021,021,016,000,000}, 0x0298 }, /* Bull's eye */
{{000,000,016,021,015,021,016,000,000}, 0x029a }, /* Closed epsilon */
{{001,002,016,020,026,022,016,000,000}, 0x029b }, /* Hooktop small capital G */
{{000,000,021,021,037,021,021,000,000}, 0x029c }, /* Small capital H */
{{004,000,004,004,004,016,024,024,010}, 0x029d }, /* Curly-tail J */
{{000,000,022,012,006,012,022,002,002}, 0x029e }, /* Turned K */
{{000,000,020,020,020,020,037,000,000}, 0x029f }, /* Small capital L */
{{006,001,017,021,021,021,017,001,001}, 0x02a0 }, /* Hooktop Q */
{{016,021,002,004,037,004,004,000,000}, 0x02a1 }, /* Barred glottal stop */
{{016,021,010,004,037,004,004,000,000}, 0x02a2 }, /* Barred reversed glottal stop */
{{004,004,017,025,026,026,017,000,000}, 0x02a3 }, /* dz ligature */
{{004,004,017,025,026,025,015,001,006}, 0x02a4 }, /* dezh ligature */
{{004,004,017,025,026,026,017,005,002}, 0x02a5 }, /* dz-curl ligature */
{{000,010,013,034,012,011,006,000,000}, 0x02a6 }, /* ts ligature */
{{001,012,012,036,012,012,006,002,004}, 0x02a7 }, /* tesh ligature */
{{000,020,023,034,024,024,016,005,002}, 0x02a8 }, /* tc-curl ligature */
{{010,020,020,036,025,025,025,001,006}, 0x02a9 }, /* feng ligature */
{{030,010,013,014,012,011,036,000,000}, 0x02aa }, /* ls ligature */
{{030,010,017,011,012,014,037,000,000}, 0x02ab }, /* lz ligature */
{{021,025,012,000,021,025,012,000,000}, 0x02ac }, /* bilabial percussive */
{{037,021,021,000,037,021,021,000,000}, 0x02ad }, /* bidental percussive */
/* Spacing modifier letters */
{{020,020,030,024,024,000,000,000,000}, 0x02b0 }, /* Superscript H */
{{010,000,010,010,010,020,000,000,000}, 0x02b2 }, /* Superscript J */
{{004,004,010,000,000,000,000,000,000}, 0x02bc }, /* Modifier apostrophe */
{{004,004,004,000,000,000,000,000,000}, 0x02c8 }, /* Vertical stroke (superior) */
{{000,000,000,000,000,000,004,004,004}, 0x02cc }, /* Vertical stroke (inferior) */
{{000,000,012,004,000,004,012,000,000}, 0x02d0 }, /* Length mark */
{{000,000,012,004,000,000,000,000,000}, 0x02d1 }, /* Half-length mark */
{{024,010,024,024,010,000,000,000,000}, 0x02e0 }, /* Superscript gamma */
{{030,010,010,010,034,000,000,000,000}, 0x02e1 }, /* Superscript L */
{{000,000,014,010,030,000,000,000,000}, 0x02e2 }, /* Superscript S */
{{000,000,024,010,024,000,000,000,000}, 0x02e3 }, /* Superscript X */
{{010,024,020,010,010,000,000,000,000}, 0x02e4 }, /* Superscript reversed glottal stop */
{{037,001,001,001,001,001,001,000,000}, 0x02e5 }, /* Extra-high tone letter */
{{001,037,001,001,001,001,001,000,000}, 0x02e6 }, /* High tone letter */
{{001,001,001,037,001,001,001,000,000}, 0x02e7 }, /* Mid tone letter */
{{001,001,001,001,001,037,001,000,000}, 0x02e8 }, /* Low tone letter */
{{001,001,001,001,001,001,037,000,000}, 0x02e9 }, /* Extra-low tone letter */
/* Greek and Coptic*/
{{004,012,021,021,037,021,021,000,000}, 0x0391, "Alpha" },
{{036,021,021,036,021,021,036,000,000}, 0x0392, "Beta" },
{{037,020,020,020,020,020,020,000,000}, 0x0393, "Gamma" },
{{004,004,012,012,021,021,037,000,000}, 0x0394 }, /* Delta */
{{037,020,020,036,020,020,037,000,000}, 0x0395, "Epsilon" },
{{037,001,002,004,010,020,037,000,000}, 0x0396, "Zeta" },
{{021,021,021,037,021,021,021,000,000}, 0x0397, "Eta" },
{{016,021,021,037,021,021,016,000,000}, 0x0398, "Theta" },
{{016,004,004,004,004,004,016,000,000}, 0x0399, "Iota" },
{{021,022,024,030,024,022,021,000,000}, 0x039a, "Kappa" },
{{004,004,012,012,021,021,021,000,000}, 0x039b, "Lambda" },
{{021,033,025,025,021,021,021,000,000}, 0x039c, "Mu" },
{{021,021,031,025,023,021,021,000,000}, 0x039d, "Nu" },
{{037,000,000,016,000,000,037,000,000}, 0x039e, "Xi" },
{{016,021,021,021,021,021,016,000,000}, 0x039f, "Omicron" },
{{037,021,021,021,021,021,021,000,000}, 0x03a0, "Pi" },
{{036,021,021,036,020,020,020,000,000}, 0x03a1, "Rho" },
{{037,020,010,004,010,020,037,000,000}, 0x03a3, "Sigma" },
{{037,004,004,004,004,004,004,000,000}, 0x03a4, "Tau" },
{{021,021,012,004,004,004,004,000,000}, 0x03a5, "Upsilon" },
{{004,016,025,025,025,016,004,000,000}, 0x03a6, "Phi" },
{{021,021,012,004,012,021,021,000,000}, 0x03a7, "Chi" },
{{025,025,025,025,025,016,004,000,000}, 0x03a8, "Psi" },
{{016,021,021,021,021,012,033,000,000}, 0x03a9 }, /* Omega */
{{000,000,015,022,022,022,015,000,000}, 0x03b1, "alpha" },
{{016,021,021,036,021,021,036,020,020}, 0x03b2, "beta" },
{{000,000,021,021,012,012,004,004,004}, 0x03b3, "gamma" },
{{017,020,016,021,021,021,016,000,000}, 0x03b4, "delta" },
{{000,000,017,020,016,020,017,000,000}, 0x03b5, "epsilon" },
{{036,002,004,010,020,020,014,002,004}, 0x03b6, "zeta" },
{{000,000,036,021,021,021,021,001,001}, 0x03b7, "eta" },
{{014,022,022,036,022,022,014,000,000}, 0x03b8, "theta" },
{{000,000,014,004,004,004,002,000,000}, 0x03b9, "iota" },
{{000,000,011,012,014,012,011,000,000}, 0x03ba, "kappa" },
{{030,004,004,012,012,021,021,000,000}, 0x03bb, "lambda" },
{{000,000,022,022,022,022,035,020,020}, 0x03bc }, /* mu */
{{000,000,021,021,011,012,004,000,000}, 0x03bd, "nu" },
{{016,020,020,016,020,020,016,001,002}, 0x03be, "xi" },
{{000,000,016,021,021,021,016,000,000}, 0x03bf, "omicron" },
{{000,000,037,012,012,012,011,000,000}, 0x03c0, "pi" },
{{000,000,016,021,021,021,036,020,020}, 0x03c1, "rho" },
{{000,000,017,020,020,020,016,001,002}, 0x03c2, "sigma1" },
{{000,000,017,022,021,021,016,000,000}, 0x03c3, "sigma" },
{{000,000,037,004,004,004,002,000,000}, 0x03c4, "tau" },
{{000,000,022,021,021,021,016,000,000}, 0x03c5, "upsilon" },
{{000,000,026,025,025,025,016,004,004}, 0x03c6, "phi" },
{{000,000,021,011,012,004,012,022,021}, 0x03c7, "chi" },
{{000,000,025,025,025,025,016,004,004}, 0x03c8, "psi" },
{{000,000,012,021,025,025,012,000,000}, 0x03c9, "omega" },
{{004,004,016,025,025,025,016,004,004}, 0x03d5, "phi1" },
#ifdef ARMENIAN
/* Armenian */
{{021,021,021,021,025,022,015,000,000}, 0x0531 }, /* Ayb */
{{016,021,021,020,037,020,020,000,000}, 0x0532 }, /* Ben */
{{014,022,022,022,017,002,002,000,000}, 0x0533 }, /* Gim */
{{014,022,022,002,003,002,002,000,000}, 0x0534 }, /* Da */
{{020,020,037,020,021,021,016,000,000}, 0x0535 }, /* Ech */
{{016,021,021,001,001,022,037,000,000}, 0x0536 }, /* Za */
{{020,020,020,037,020,020,036,000,000}, 0x0537 }, /* Eh */
{{016,021,021,020,020,020,037,000,000}, 0x0538 }, /* Et */
{{016,021,021,023,025,025,022,000,000}, 0x0539 }, /* To */
{{002,002,017,022,022,022,014,000,000}, 0x053a }, /* Zhe */
{{020,020,036,021,021,021,020,000,000}, 0x053b }, /* Ini */
{{020,020,020,020,020,020,037,000,000}, 0x053c }, /* Liwn */
{{020,020,035,025,025,025,022,000,000}, 0x053d }, /* Xeh */
{{037,016,021,021,021,021,016,000,000}, 0x053e }, /* Ca */
{{020,021,021,017,001,001,001,000,000}, 0x053f }, /* Ken */
{{002,001,003,014,020,014,003,000,000}, 0x0540 }, /* Ho */
{{016,021,021,001,015,022,015,000,000}, 0x0541 }, /* Ja */
{{014,022,022,002,002,002,003,000,000}, 0x0542 }, /* Ghad */
{{001,032,004,012,012,021,037,000,000}, 0x0543 }, /* Cheh */
{{023,022,022,022,022,022,014,000,000}, 0x0544 }, /* Men */
{{016,021,001,036,001,021,016,000,000}, 0x0545 }, /* Yi */
{{030,010,010,010,011,011,006,000,000}, 0x0546 }, /* Now */
{{030,007,010,020,021,021,016,000,000}, 0x0547 }, /* Sha */
{{016,021,021,021,021,021,021,000,000}, 0x0548 }, /* Vo */
{{016,021,021,001,002,034,003,000,000}, 0x0549 }, /* Cha */
{{016,025,025,005,005,001,001,000,000}, 0x054a }, /* Peh */
{{016,021,021,031,005,026,037,000,000}, 0x054b }, /* Jheh */
{{014,022,022,023,022,022,022,000,000}, 0x054c }, /* Ra */
{{021,021,021,021,021,021,016,000,000}, 0x054d }, /* Seh */
{{002,022,022,022,016,002,003,000,000}, 0x054e }, /* Vew */
{{016,021,020,016,001,021,016,000,000}, 0x054f }, /* Tiwn */
{{016,021,021,020,020,020,020,000,000}, 0x0550 }, /* Reh */
{{016,021,016,021,001,021,016,000,000}, 0x0551 }, /* Co */
{{020,020,037,020,020,020,020,000,000}, 0x0552 }, /* Yiwn */
{{004,016,025,025,025,016,004,000,000}, 0x0553 }, /* Piwr */
{{006,011,011,016,010,037,010,000,000}, 0x0554 }, /* Keh */
{{016,021,021,021,021,021,016,000,000}, 0x0555 }, /* Oh */
{{014,024,016,005,025,025,016,000,000}, 0x0556 }, /* Feh */
{{000,000,025,025,025,025,013,000,000}, 0x0561 }, /* ayb */
{{000,000,036,021,021,020,037,020,020}, 0x0562 }, /* ben */
{{000,000,016,022,022,022,017,002,002}, 0x0563 }, /* gim */
{{000,000,034,022,022,022,023,002,002}, 0x0564 }, /* da */
{{020,020,037,020,021,021,017,000,000}, 0x0565 }, /* ech */
{{000,000,016,022,022,022,016,002,003}, 0x0566 }, /* za */
{{020,020,037,020,020,020,036,000,000}, 0x0567 }, /* eh */
{{000,000,036,021,021,021,021,020,037}, 0x0568 }, /* et */
{{000,000,036,021,027,031,026,020,020}, 0x0569 }, /* to */
{{002,002,017,022,022,022,014,000,000}, 0x056a }, /* zhe */
{{020,020,036,021,021,021,021,020,020}, 0x056b }, /* ini */
{{000,000,010,010,010,010,010,010,016}, 0x056c }, /* liwn */
{{020,020,035,025,025,025,023,020,020}, 0x056d }, /* xeh */
{{004,002,017,022,022,022,014,000,000}, 0x056e }, /* ca */
{{020,020,021,021,021,021,017,001,001}, 0x056f }, /* ken */
{{020,020,036,021,021,021,021,000,000}, 0x0570 }, /* ho */
{{004,002,004,012,021,023,015,000,000}, 0x0571 }, /* ja */
{{000,000,034,022,022,022,022,002,003}, 0x0572 }, /* ghad */
{{007,010,036,011,011,011,007,000,000}, 0x0573 }, /* cheh */
{{003,002,022,022,022,022,016,000,000}, 0x0574 }, /* men */
{{000,000,004,004,004,004,004,004,010}, 0x0575 }, /* yi */
{{030,010,011,011,011,011,007,000,000}, 0x0576 }, /* now */
{{000,000,016,021,001,002,014,020,037}, 0x0577 }, /* sha */
{{000,000,036,021,021,021,021,000,000}, 0x0578 }, /* vo */
{{000,000,004,010,004,002,014,020,037}, 0x0579 }, /* cha */
{{000,000,025,025,025,025,013,001,001}, 0x057a }, /* peh */
{{000,000,016,021,021,012,014,020,037}, 0x057b }, /* jheh */
{{000,000,036,021,021,022,023,000,000}, 0x057c }, /* ra */
{{000,000,021,021,021,021,017,000,000}, 0x057d }, /* seh */
{{002,002,022,022,022,022,016,002,003}, 0x057e }, /* vew */
{{000,000,026,025,025,025,015,000,000}, 0x057f }, /* tiwn */
{{000,000,036,021,021,021,021,020,020}, 0x0580 }, /* reh */
{{000,000,017,021,021,021,017,001,016}, 0x0581 }, /* co */
{{000,000,010,010,010,010,016,000,000}, 0x0582 }, /* yiwn */
{{004,004,026,025,025,025,015,004,004}, 0x0583 }, /* piwr */
{{000,000,016,011,011,016,010,037,010}, 0x0584 }, /* keh */
{{000,000,016,021,021,021,016,000,000}, 0x0585 }, /* oh */
{{014,024,016,005,025,025,016,004,004}, 0x0586 }, /* feh */
{{020,020,024,024,024,024,017,000,000}, 0x0587 }, /* ech_yiwn */
{{014,022,022,007,002,007,002,000,000}, 0x058f }, /* armdram */
#endif
/* Phonetic extensions */
{{030,004,034,024,010,000,000,000,000}, 0x1d4a }, /* Superscript schwa */
{{000,000,000,000,004,000,014,004,016}, 0x1d62 }, /* iinferior */
{{010,024,034,024,010,000,000,000,000}, 0x1dbf }, /* Superscript theta */
/* Latin Extended Additional */
{{017,021,022,026,021,021,026,000,000}, -1, "uni1E9E.dresden" },
{{037,021,022,026,021,021,026,000,000}, -1, "uni1E9E.angular" },
{{016,021,023,024,022,021,026,000,000}, -1, "uni1E9E.leipzig" },
{{016,021,022,022,021,021,026,000,000}, -1, "uni1E9E.zehlendorf" },
/* General punctuation */
{{000,000,000,036,000,000,000,000,000}, 0x2013, "endash" },
{{000,000,000,000,000,000,037,000,037}, 0x2017, "underscoredbl" },
{{002,004,004,000,000,000,000,000,000}, 0x2018, "quoteleft" },
{{000,000,000,000,000,004,004,010,000}, 0x201a, "quotesinglbase" },
{{011,022,022,000,000,000,000,000,000}, 0x201c, "quotedblleft" },
{{011,011,022,000,000,000,000,000,000}, 0x201d, "quotedblright" },
{{000,000,000,000,000,011,011,022,000}, 0x201e, "quotedblbase" },
{{022,022,011,000,000,000,000,000,000}, 0x201f }, /* quotedblreversed */
{{000,000,016,016,016,000,000,000,000}, 0x2022, "bullet" },
{{025,021,012,004,025,004,012,021,025}, 0x203b }, /* referencemark */
{{000,000,000,000,000,000,000,021,016}, 0x203f }, /* Bottom tie bar */
{{012,012,012,012,012,000,012,000,000}, 0x203c, "exclamdbl" },
/* Subscripts and superscripts */
{{004,012,012,012,004,000,000,000,000}, 0x2070 }, /* zerosuperior */
{{004,000,014,004,016,000,000,000,000}, 0x2071 }, /* isuperior */
{{002,006,012,016,002,000,000,000,000}, 0x2074 }, /* foursuperior */
{{016,010,014,002,014,000,000,000,000}, 0x2075 }, /* fivesuperior */
{{004,010,014,012,004,000,000,000,000}, 0x2076 }, /* sixsuperior */
{{016,002,004,010,010,000,000,000,000}, 0x2077 }, /* sevensuperior */
{{004,012,004,012,004,000,000,000,000}, 0x2078 }, /* eightsuperior */
{{004,012,006,002,004,000,000,000,000}, 0x2079 }, /* ninesuperior */
{{000,004,016,004,000,000,000,000,000}, 0x207a }, /* plussuperior */
{{000,000,016,000,000,000,000,000,000}, 0x207b }, /* minussuperior */
{{000,016,000,016,000,000,000,000,000}, 0x207c }, /* equalssuperior */
{{002,004,004,004,002,000,000,000,000}, 0x207d }, /* parenleftsuperior */
{{010,004,004,004,010,000,000,000,000}, 0x207e }, /* parenrightsuperior */
{{000,000,014,012,012,000,000,000,000}, 0x207f }, /* nsuperior */
{{000,000,000,000,004,012,012,012,004}, 0x2080 }, /* zeroinferior */
{{000,000,000,000,004,014,004,004,016}, 0x2081 }, /* oneinferior */
{{000,000,000,000,014,002,004,010,016}, 0x2082 }, /* twoinferior */
{{000,000,000,000,014,002,014,002,014}, 0x2083 }, /* threeinferior */
{{000,000,000,000,002,006,012,016,002}, 0x2084 }, /* fourinferior */
{{000,000,000,000,016,010,014,002,014}, 0x2085 }, /* fiveinferior */
{{000,000,000,000,004,010,014,012,004}, 0x2086 }, /* sixinferior */
{{000,000,000,000,016,002,004,010,010}, 0x2087 }, /* seveninferior */
{{000,000,000,000,004,012,004,012,004}, 0x2088 }, /* eightinferior */
{{000,000,000,000,004,012,006,002,004}, 0x2089 }, /* nineinferior */
{{000,000,000,000,000,004,016,004,000}, 0x208a }, /* plusinferior */
{{000,000,000,000,000,000,016,000,000}, 0x208b }, /* minusinferior */
{{000,000,000,000,000,016,000,016,000}, 0x208c }, /* equalsinferior */
{{000,000,000,000,002,004,004,004,002}, 0x208d }, /* parenleftinferior */
{{000,000,000,000,010,004,004,004,010}, 0x208e }, /* parenrightinferior */
{{000,000,000,000,000,000,014,012,012}, 0x2099 }, /* ninferior */
/* Currency symbols */
{{030,024,030,022,027,022,021,000,000}, 0x20a7, "peseta" },
{{031,025,025,021,025,025,026,000,000}, 0x20aa }, /* newsheqel */
{{006,011,034,010,034,011,006,000,000}, 0x20ac, "Euro" },
/* Letterlike symbols */
{{016,021,035,033,033,035,031,021,016}, 0x2117 }, /* phonographic */
/* Number forms */
{{020,020,020,020,027,001,002,004,004}, 0x2150 }, /* oneseventh */
{{020,020,020,020,022,005,003,001,002}, 0x2151 }, /* oneninth */
{{010,010,010,010,000,022,025,025,022}, 0x2152 }, /* onetenth */
{{020,020,020,020,026,001,006,001,006}, 0x2153, "onethird" },
{{020,010,010,020,032,001,002,001,002}, 0x2154, "twothirds" },
{{020,020,020,020,027,004,006,001,006}, 0x2155 }, /* onefifth */
{{020,010,010,020,033,002,003,001,002}, 0x2156 }, /* twofifths */
{{020,010,020,010,023,002,003,001,002}, 0x2157 }, /* threefifths */
{{004,014,024,034,007,002,003,001,002}, 0x2158 }, /* fourfifths */
{{020,020,020,020,022,004,006,005,002}, 0x2159 }, /* onesixth */
{{030,020,030,010,022,004,006,005,002}, 0x215a }, /* fivesixths */
{{020,020,020,020,022,005,002,005,002}, 0x215b, "oneeighth" },
{{020,010,020,010,022,005,002,005,002}, 0x215c, "threeeighths" },
{{030,020,030,010,022,005,002,005,002}, 0x215d, "fiveeighths" },
{{034,004,010,020,022,005,002,005,002}, 0x215e, "seveneighths" },
{{010,024,024,010,002,001,002,001,002}, 0x2189 }, /* zerothirds */
/* Arrows */
{{000,004,004,025,016,004,000,000,000}, 0x2193, "arrowdown" },
{{000,012,021,037,021,012,000,000,000}, 0x2194, "arrowboth" },
{{004,016,025,004,025,016,004,000,000}, 0x2195, "arrowupdn" },
{{000,036,030,024,022,001,000,000,000}, 0x2196 }, /* arrowupleft */
{{000,017,003,005,011,020,000,000,000}, 0x2197 }, /* arrowupright */
{{000,020,011,005,003,017,000,000,000}, 0x2198 }, /* arrowdownright */
{{000,001,022,024,030,036,000,000,000}, 0x2199 }, /* arrowdownleft */
{{000,005,011,037,011,005,000,000,000}, 0x21a4 }, /* arrowbarleft */
{{000,004,016,025,004,037,000,000,000}, 0x21a5 }, /* arrowbarup" */
{{000,024,022,037,022,024,000,000,000}, 0x21a6 }, /* arrowbarright */
{{000,037,004,025,016,004,000,000,000}, 0x21a7 }, /* arrowbardown */
{{004,016,025,004,025,016,037,000,000}, 0x21a8, "arrowupdnbse" },
{{000,034,004,025,016,004,000,000,000}, 0x21b4 }, /* arrow right then down */
{{001,005,011,037,010,004,000,000,000}, 0x21b5, "carriagereturn" },
{{000,004,010,037,000,000,000,000,000}, 0x21bc }, /* harpoonleftbarbup */
{{000,000,000,037,010,004,000,000,000}, 0x21bd }, /* harpoonleftbarbdown */
{{000,004,006,005,004,004,000,000,000}, 0x21be }, /* harpoonupbarbright */
{{000,004,014,024,004,004,000,000,000}, 0x21bf }, /* harpoonupbarbleft */
{{000,004,002,037,000,000,000,000,000}, 0x21c0 }, /* harpoonrightbarbup */
{{000,000,000,037,002,004,000,000,000}, 0x21c1 }, /* harpoonrightbarbdown */
{{000,004,004,005,006,004,000,000,000}, 0x21c2 }, /* harpoondownbarbright */
{{000,004,004,024,014,004,000,000,000}, 0x21c3 }, /* harpoondownbarbleft */
{{004,010,037,000,037,002,004,000,000}, 0x21cb }, /* harpoonsleftright */
{{004,002,037,000,037,010,004,000,000}, 0x21cc }, /* harpoonsrightleft */
{{000,024,030,037,030,024,000,000,000}, 0x21e4 }, /* arrowtableft */
{{000,005,003,037,003,005,000,000,000}, 0x21e5 }, /* arrowtabright */
{{000,004,010,023,010,004,000,000,000}, -1, "arrowleft.alt" },
{{000,004,002,031,002,004,000,000,000}, -1, "arrowright.alt" },
{{000,004,012,021,004,004,000,000,000}, -1, "arrowup.alt" },
{{000,004,004,021,012,004,000,000,000}, -1, "arrowdown.alt" },
/* Mathematical operators */
{{000,000,000,037,000,000,000,000,000}, 0x2212, "minus" },
{{037,000,004,004,037,004,004,000,000}, 0x2213 }, /* minusplus */
{{000,000,004,016,004,000,000,000,000}, 0x2219 }, /* bulletoperator */
{{007,004,004,004,024,014,004,000,000}, 0x221a, "radical" },
{{000,012,025,025,025,012,000,000,000}, 0x221e, "infinity" },
{{000,020,020,020,020,037,000,000,000}, 0x221f, "orthogonal" },
{{000,016,021,021,021,021,000,000,000}, 0x2229, "intersection" },
{{000,021,021,021,021,016,000,000,000}, 0x222a, "union" },
{{000,010,024,025,005,002,000,000,000}, 0x223f }, /* sinewave */
{{000,010,025,002,010,025,002,000,000}, 0x2248, "approxequal" },
{{000,002,037,004,037,010,000,000,000}, 0x2260, "notequal" },
{{000,037,000,037,000,037,000,000,000}, 0x2261, "equivalence" },
{{003,014,020,014,003,030,007,000,000}, 0x2264, "lessequal" },
{{030,006,001,006,030,003,034,000,000}, 0x2265, "greaterequal" },
/* Miscellaneous technical */
{{004,012,021,021,021,021,037,000,000}, 0x2302, "house" },
{{000,000,037,020,020,000,000,000,000}, 0x2310, "revlogicalnot" },
{{000,000,002,005,004,004,004,004,004}, 0x2320, "integraltp" },
{{004,004,004,004,004,024,010,000,000}, 0x2321, "integralbt" },
{{000,000,037,000,025,000,000,000,000}, 0x2393 }, /* directcurrent */
{{037,000,000,000,000,000,000,000,000}, 0x23ba }, /* horizontal scan 1 */
{{000,000,037,000,000,000,000,000,000}, 0x23bb }, /* horizontal scan 3 */
{{000,000,000,000,000,000,037,000,000}, 0x23bc }, /* horizontal scan 7 */
{{000,000,000,000,000,000,000,000,037}, 0x23bd }, /* horizontal scan 9 */
/* Control pictures */
{{024,034,024,000,007,002,002,000,000}, 0x2409 }, /* DEC graphics HT */
{{030,020,030,023,002,003,002,000,000}, 0x240c }, /* DEC graphics FF */
{{014,020,020,016,005,006,005,000,000}, 0x240d }, /* DEC graphics CR */
{{020,020,020,033,002,003,002,000,000}, 0x240a }, /* DEC graphics LF */
{{024,024,010,000,007,002,002,000,000}, 0x240b }, /* DEC graphics VT */
{{032,026,022,000,010,010,017,000,000}, 0x2424 }, /* DEC graphics NL */
/* Box drawing */
{{000,000,000,000,037,000,000,000,000}, 0x2500, "SF100000" },
{{000,000,000,037,037,037,000,000,000}, 0x2501 },
{{004,004,004,004,004,004,004,004,004}, 0x2502, "SF110000" },
{{016,016,016,016,016,016,016,016,016}, 0x2503 },
{{000,000,000,000,007,004,004,004,004}, 0x250c, "SF010000" },
{{000,000,000,007,007,007,004,004,004}, 0x250d },
{{000,000,000,000,017,016,016,016,016}, 0x250e },
{{000,000,000,017,017,017,016,016,016}, 0x250f },
{{000,000,000,000,034,004,004,004,004}, 0x2510, "SF030000" },
{{000,000,000,034,034,034,004,004,004}, 0x2511 },
{{000,000,000,000,036,016,016,016,016}, 0x2512 },
{{000,000,000,036,036,036,016,016,016}, 0x2513 },
{{004,004,004,004,007,000,000,000,000}, 0x2514, "SF020000" },
{{004,004,004,007,007,007,000,000,000}, 0x2515 },
{{016,016,016,016,017,000,000,000,000}, 0x2516 },
{{016,016,016,017,017,017,000,000,000}, 0x2517 },
{{004,004,004,004,034,000,000,000,000}, 0x2518, "SF040000" },
{{004,004,004,034,034,034,000,000,000}, 0x2519 },
{{016,016,016,016,036,000,000,000,000}, 0x251a },
{{016,016,016,036,036,036,000,000,000}, 0x251b },
{{004,004,004,004,007,004,004,004,004}, 0x251c, "SF080000" },
{{004,004,004,007,007,007,004,004,004}, 0x251d },
{{016,016,016,016,017,004,004,004,004}, 0x251e },
{{004,004,004,004,017,016,016,016,016}, 0x251f },
{{016,016,016,016,017,016,016,016,016}, 0x2520 },
{{016,016,016,017,017,017,004,004,004}, 0x2521 },
{{004,004,004,017,017,017,016,016,016}, 0x2522 },
{{016,016,016,017,017,017,016,016,016}, 0x2523 },
{{004,004,004,004,034,004,004,004,004}, 0x2524, "SF090000" },
{{004,004,004,034,034,034,004,004,004}, 0x2525 },
{{016,016,016,016,036,004,004,004,004}, 0x2526 },
{{004,004,004,004,036,016,016,016,016}, 0x2527 },
{{016,016,016,016,036,016,016,016,016}, 0x2528 },
{{016,016,016,036,036,036,004,004,004}, 0x2529 },
{{004,004,004,036,036,036,016,016,016}, 0x252a },
{{016,016,016,036,036,036,016,016,016}, 0x252b },
{{000,000,000,000,037,004,004,004,004}, 0x252c, "SF060000" },
{{000,000,000,034,037,034,004,004,004}, 0x252d },
{{000,000,000,007,037,007,004,004,004}, 0x252e },
{{000,000,000,037,037,037,004,004,004}, 0x252f },
{{000,000,000,000,037,016,016,016,016}, 0x2530 },
{{000,000,000,036,037,036,016,016,016}, 0x2531 },
{{000,000,000,017,037,017,016,016,016}, 0x2532 },
{{000,000,000,037,037,037,016,016,016}, 0x2533 },
{{004,004,004,004,037,000,000,000,000}, 0x2534, "SF070000" },
{{004,004,004,034,037,034,000,000,000}, 0x2535 },
{{004,004,004,007,037,007,000,000,000}, 0x2536 },
{{004,004,004,037,037,037,000,000,000}, 0x2537 },
{{016,016,016,016,037,000,000,000,000}, 0x2538 },
{{016,016,016,036,037,036,000,000,000}, 0x2539 },
{{016,016,016,017,037,017,000,000,000}, 0x253a },
{{016,016,016,037,037,037,000,000,000}, 0x253b },
{{004,004,004,004,037,004,004,004,004}, 0x253c, "SF050000" },
{{004,004,004,034,037,034,004,004,004}, 0x253d },
{{004,004,004,007,037,007,004,004,004}, 0x253e },
{{004,004,004,037,037,037,004,004,004}, 0x253f },
{{016,016,016,016,037,004,004,004,004}, 0x2540 },
{{004,004,004,004,037,016,016,016,016}, 0x2541 },
{{016,016,016,016,037,016,016,016,016}, 0x2542 },
{{016,016,016,036,037,036,004,004,004}, 0x2543 },
{{016,016,016,017,037,017,004,004,004}, 0x2544 },
{{004,004,004,036,037,036,016,016,016}, 0x2545 },
{{004,004,004,017,037,017,016,016,016}, 0x2546 },
{{016,016,016,037,037,037,004,004,004}, 0x2547 },
{{004,004,004,037,037,037,016,016,016}, 0x2548 },
{{016,016,016,036,037,036,016,016,016}, 0x2549 },
{{016,016,016,017,037,017,016,016,016}, 0x254a },
{{016,016,016,037,037,037,016,016,016}, 0x254b },
{{000,000,000,037,000,037,000,000,000}, 0x2550, "SF430000" },
{{012,012,012,012,012,012,012,012,012}, 0x2551, "SF240000" },
{{000,000,000,007,004,007,004,004,004}, 0x2552, "SF510000" },
{{000,000,000,000,017,012,012,012,012}, 0x2553, "SF520000" },
{{000,000,000,017,010,013,012,012,012}, 0x2554, "SF390000" },
{{000,000,000,034,004,034,004,004,004}, 0x2555, "SF220000" },
{{000,000,000,000,036,012,012,012,012}, 0x2556, "SF210000" },
{{000,000,000,036,002,032,012,012,012}, 0x2557, "SF250000" },
{{004,004,004,007,004,007,000,000,000}, 0x2558, "SF500000" },
{{012,012,012,012,017,000,000,000,000}, 0x2559, "SF490000" },
{{012,012,012,013,010,017,000,000,000}, 0x255a, "SF380000" },
{{004,004,004,034,004,034,000,000,000}, 0x255b, "SF280000" },
{{012,012,012,012,036,000,000,000,000}, 0x255c, "SF270000" },
{{012,012,012,032,002,036,000,000,000}, 0x255d, "SF260000" },
{{004,004,004,007,004,007,004,004,004}, 0x255e, "SF360000" },
{{012,012,012,012,013,012,012,012,012}, 0x255f, "SF370000" },
{{012,012,012,013,010,013,012,012,012}, 0x2560, "SF420000" },
{{004,004,004,034,004,034,004,004,004}, 0x2561, "SF190000" },
{{012,012,012,012,032,012,012,012,012}, 0x2562, "SF200000" },
{{012,012,012,032,002,032,012,012,012}, 0x2563, "SF230000" },
{{000,000,000,037,000,037,004,004,004}, 0x2564, "SF470000" },
{{000,000,000,000,037,012,012,012,012}, 0x2565, "SF480000" },
{{000,000,000,037,000,033,012,012,012}, 0x2566, "SF410000" },
{{004,004,004,037,000,037,000,000,000}, 0x2567, "SF450000" },
{{012,012,012,012,037,000,000,000,000}, 0x2568, "SF460000" },
{{012,012,012,033,000,037,000,000,000}, 0x2569, "SF400000" },
{{004,004,004,037,004,037,004,004,004}, 0x256a, "SF540000" },
{{012,012,012,012,037,012,012,012,012}, 0x256b, "SF530000" },
{{012,012,012,033,000,033,012,012,012}, 0x256c, "SF440000" },
/* Block elements */
{{037,037,037,037,037,000,000,000,000}, 0x2580, "upblock" },
{{000,000,000,000,037,037,037,037,037}, 0x2584, "dnblock" },
{{037,037,037,037,037,037,037,037,037}, 0x2588, "block" },
{{034,034,034,034,034,034,034,034,034}, 0x258c, "lfblock" },
{{007,007,007,007,007,007,007,007,007}, 0x2590, "rtblock" },
{{025,000,012,000,025,000,012,000,025}, 0x2591, "ltshade" },
{{022,011,004,022,011,004,022,011,004}, 0x2592, "shade" },
{{025,037,012,037,025,037,012,037,025}, 0x2593, "dkshade" },
/* Geometric shapes */
{{037,021,021,021,021,021,037,000,000}, 0x25a1, "H22073" },
{{000,000,016,016,016,000,000,000,000}, 0x25aa, "H18543" },
{{000,000,016,012,016,000,000,000,000}, 0x25ab, "H18551" },
{{000,000,037,037,037,000,000,000,000}, 0x25ac, "filledrect" },
{{000,000,037,021,037,000,000,000,000}, 0x25ad }, /* rect */
{{004,004,016,016,037,037,037,000,000}, 0x25b2, "triagup" },
{{010,014,016,017,016,014,010,000,000}, 0x25b6 }, /* blacktriangleright */
{{000,020,034,037,034,020,000,000,000}, 0x25ba, "triagrt" },
{{037,037,037,016,016,004,004,000,000}, 0x25bc, "triagdn" },
{{001,003,007,017,007,003,001,000,000}, 0x25c0 }, /* blacktriangleleft */
{{000,001,007,037,007,001,000,000,000}, 0x25c4, "triaglf" },
{{000,016,021,021,021,016,000,000,000}, 0x25cb, "circle" },
{{000,004,021,000,021,004,000,000,000}, 0x25cc }, /* dottedcircle */
{{000,016,037,037,037,016,000,000,000}, 0x25cf, "H18533" },
{{037,037,021,021,021,037,037,000,000}, 0x25d8, "invbullet" },
{{037,021,004,016,004,021,037,000,000}, 0x25d9, "invcircle" },
{{000,037,025,035,021,037,000,000,000}, 0x25f0 }, /* square upper left quad */
{{000,037,021,035,025,037,000,000,000}, 0x25f1 }, /* square lower left quad */
{{000,037,025,027,021,037,000,000,000}, 0x25f2 }, /* square lower right quad */
{{000,037,021,027,025,037,000,000,000}, 0x25f3 }, /* square upper right quad */
{{000,016,025,035,021,016,000,000,000}, 0x25f4 }, /* circle upper left quad */
{{000,016,021,035,025,016,000,000,000}, 0x25f5 }, /* circle lower left quad */
{{000,016,025,027,021,016,000,000,000}, 0x25f6 }, /* circle lower right quad */
{{000,016,021,027,025,016,000,000,000}, 0x25f7 }, /* circle upper right quad */
/* Miscellaneous symbols */
{{001,002,004,010,005,003,007,000,000}, 0x2607 }, /* lightning */
{{037,022,024,030,025,023,027,000,000}, 0x2608 }, /* thunderstorm */
{{000,016,021,025,021,016,000,000,000}, 0x2609 }, /* astrological sun */
{{000,012,000,000,021,016,000,000,000}, 0x263a, "smileface" },
{{000,016,025,037,021,016,000,000,000}, 0x263b, "invsmileface" },
{{000,025,016,033,016,025,000,000,000}, 0x263c, "sun" },
{{016,021,021,016,004,016,004,000,000}, 0x2640, "female" },
{{007,003,005,014,022,022,014,000,000}, 0x2642, "male" },
{{000,004,016,037,037,004,016,000,000}, 0x2660, "spade" },
{{000,016,016,037,037,004,016,000,000}, 0x2663, "club" },
{{000,012,037,037,016,004,000,000,000}, 0x2665, "heart" },
{{000,004,016,037,016,004,000,000,000}, 0x2666, "diamond" },
{{002,002,002,002,006,016,004,000,000}, 0x2669 }, /* crotchet */
{{004,006,005,005,014,034,010,000,000}, 0x266a, "musicalnote" },
{{003,015,011,011,013,033,030,000,000}, 0x266b, "musicalnotedbl" },
{{017,011,017,011,011,033,033,000,000}, 0x266c }, /* semiquavers */
{{010,010,013,015,011,012,014,000,000}, 0x266d }, /* flat */
{{010,013,015,011,013,015,001,000,000}, 0x266e }, /* natural */
{{002,013,016,033,016,032,010,000,000}, 0x266f }, /* sharp */
/* Dingbats */
{{000,004,022,017,022,004,000,000,000}, 0x2708 }, /* airplane */
/* Supplemental arrows-B */
{{000,037,016,025,004,004,000,000,000}, 0x2912 }, /* arrowupbar */
{{000,004,004,025,016,037,000,000,000}, 0x2913 }, /* arrowdownbar */
{{000,004,016,025,004,030,000,000,000}, 0x2934 }, /* arrow right curve up */
{{000,030,004,025,016,004,000,000,000}, 0x2935 }, /* arrow right curve down */
{{001,005,011,036,010,004,000,000,000}, 0x2936 }, /* arrow down curve left */
{{020,024,022,017,002,004,000,000,000}, 0x2937 }, /* arrow down curve right */
{{000,024,030,037,020,020,000,000,000}, 0x2952 }, /* harpoons to bars... */
{{000,005,003,037,001,001,000,000,000}, 0x2953 },
{{000,037,006,005,004,004,000,000,000}, 0x2954 },
{{000,004,004,005,006,037,000,000,000}, 0x2955 },
{{000,020,020,037,030,024,000,000,000}, 0x2956 },
{{000,001,001,037,003,005,000,000,000}, 0x2957 },
{{000,037,014,024,004,004,000,000,000}, 0x2958 },
{{000,004,004,024,014,037,000,000,000}, 0x2959 },
{{000,005,011,037,001,001,000,000,000}, 0x295a }, /* ... and from bars */
{{000,024,022,037,020,020,000,000,000}, 0x295b },
{{000,004,006,005,004,037,000,000,000}, 0x295c },
{{000,037,004,005,006,004,000,000,000}, 0x295d },
{{000,001,001,037,011,005,000,000,000}, 0x295e },
{{000,020,020,037,022,024,000,000,000}, 0x295f },
{{000,004,014,024,004,037,000,000,000}, 0x2960 },
{{000,037,004,024,014,004,000,000,000}, 0x2961 },
/* Miscellaneous symbols and arrows */
{{000,025,000,021,000,025,000,000,000}, 0x2b1a }, /* dottedsquare */
/* Latin Extended-C */
{{000,000,022,025,024,024,010,000,000}, 0x2c71 }, /* vhook */
/* Private use */
/* U+EE00--U+EE7F: zvbi mosaic graphics */
#define M(x) {{(x)}, 0xee00 + (x), NULL, MOS}
M(0x00), M(0x01), M(0x02), M(0x03), M(0x04), M(0x05), M(0x06), M(0x07),
M(0x08), M(0x09), M(0x0a), M(0x0b), M(0x0c), M(0x0d), M(0x0e), M(0x0f),
M(0x10), M(0x11), M(0x12), M(0x13), M(0x14), M(0x15), M(0x16), M(0x17),
M(0x18), M(0x19), M(0x1a), M(0x1b), M(0x1c), M(0x1d), M(0x1e), M(0x1f),
M(0x20), M(0x21), M(0x22), M(0x23), M(0x24), M(0x25), M(0x26), M(0x27),
M(0x28), M(0x29), M(0x2a), M(0x2b), M(0x2c), M(0x2d), M(0x2e), M(0x2f),
M(0x30), M(0x31), M(0x32), M(0x33), M(0x34), M(0x35), M(0x36), M(0x37),
M(0x38), M(0x39), M(0x3a), M(0x3b), M(0x3c), M(0x3d), M(0x3e), M(0x3f),
M(0x40), M(0x41), M(0x42), M(0x43), M(0x44), M(0x45), M(0x46), M(0x47),
M(0x48), M(0x49), M(0x4a), M(0x4b), M(0x4c), M(0x4d), M(0x4e), M(0x4f),
M(0x50), M(0x51), M(0x52), M(0x53), M(0x54), M(0x55), M(0x56), M(0x57),
M(0x58), M(0x59), M(0x5a), M(0x5b), M(0x5c), M(0x5d), M(0x5e), M(0x5f),
M(0x60), M(0x61), M(0x62), M(0x63), M(0x64), M(0x65), M(0x66), M(0x67),
M(0x68), M(0x69), M(0x6a), M(0x6b), M(0x6c), M(0x6d), M(0x6e), M(0x6f),
M(0x70), M(0x71), M(0x72), M(0x73), M(0x74), M(0x75), M(0x76), M(0x77),
M(0x78), M(0x79), M(0x7a), M(0x7b), M(0x7c), M(0x7d), M(0x7e), M(0x7f),
/* Specials */
{{016,021,025,011,016,012,016,000,000}, 0xfffd }, /* replacement */
{{037,021,021,021,021,021,037,000,000}, -1, ".notdef" },
/* Transport and map symbols */
{{000,034,010,011,027,010,000,000,000}, 0x1f681 }, /* helicopter */
/* Latin small caps */
{{000,000,016,021,037,021,021,000,000}, -1, "a.sc" },
{{000,000,036,021,036,021,036,000,000}, -1, "b.sc" },
{{000,000,016,021,020,021,016,000,000}, -1, "c.sc" },
{{000,000,036,021,021,021,036,000,000}, -1, "d.sc" },
{{000,000,037,020,036,020,037,000,000}, -1, "e.sc" },
{{000,000,037,020,036,020,020,000,000}, -1, "f.sc" },
{{000,000,017,020,023,021,017,000,000}, -1, "g.sc" },
{{000,000,021,021,037,021,021,000,000}, -1, "h.sc" },
{{000,000,016,004,004,004,016,000,000}, -1, "i.sc" },
{{000,000,001,001,001,021,016,000,000}, -1, "j.sc" },
{{000,000,021,022,034,022,021,000,000}, -1, "k.sc" },
{{000,000,020,020,020,020,037,000,000}, -1, "l.sc" },
{{000,000,021,033,025,021,021,000,000}, -1, "m.sc" },
{{000,000,021,031,025,023,021,000,000}, -1, "n.sc" },
{{000,000,016,021,021,021,016,000,000}, -1, "o.sc" },
{{000,000,036,021,036,020,020,000,000}, -1, "p.sc" },
{{000,000,016,021,025,022,015,000,000}, -1, "q.sc" },
{{000,000,036,021,036,022,021,000,000}, -1, "r.sc" },
{{000,000,017,020,016,001,036,000,000}, -1, "s.sc" },
{{000,000,037,004,004,004,004,000,000}, -1, "t.sc" },
{{000,000,021,021,021,021,016,000,000}, -1, "u.sc" },
{{000,000,021,021,012,012,004,000,000}, -1, "v.sc" },
{{000,000,021,021,025,025,012,000,000}, -1, "w.sc" },
{{000,000,021,012,004,012,021,000,000}, -1, "x.sc" },
{{000,000,021,012,004,004,004,000,000}, -1, "y.sc" },
{{000,000,037,001,016,020,037,000,000}, -1, "z.sc" },
};
static void dolookups(struct glyph const *);
static inline int
getpix(char const data[YSIZE], int x, int y, unsigned flags)
{
if (x < 0 || x >= XSIZE || y < 0 || y >= YSIZE)
return 0;
else
return (data[y] >> (XSIZE - x - 1)) & 1;
}
int
main(int argc, char **argv)
{
int i;
int const nglyphs = sizeof(glyphs) / sizeof(glyphs[0]);
int extraglyphs = 0;
char *endptr;
while (argc > 1) {
if (strcmp(argv[1], "--extended") == 0) {
param = &extended_param;
argv++; argc--;
} else if (strcmp(argv[1], "--condensed") == 0) {
param = &condensed_param;
argv++; argc--;
} else if (strcmp(argv[1], "--semicondensed") == 0) {
param = &semicondensed_param;
argv++; argc--;
} else if (strcmp(argv[1], "--") == 0) {
argv++; argc--;
break;
} else if (argv[1][0] == '-') {
fprintf(stderr, "unknown option '%s'\n", argv[1]);
return 1;
} else break;
argv++; argc--;
}
if (argc > 1) {
char data[YSIZE];
int i, y;
unsigned long u;
for (y = 0; y < YSIZE; y++)
data[y] = 0;
y = 0;
for (i = 1; i < argc; i++) {
if (y >= YSIZE) {
fprintf(stderr, "too many arguments\n");
return 1;
}
u = strtoul(argv[i], &endptr, 0);
if (u > 077 || !argv[i] || *endptr) {
fprintf(stderr, "invalid argument \"%s\"\n",
argv[i]);
return 1;
}
data[y++] = u;
}
dochar(data, 0);
return 0;
}
for (i = 0; i < nglyphs; i++)
if (glyphs[i].unicode == -1)
extraglyphs++;
printf("SplineFontDB: 3.0\n");
printf("FontName: %s\n", param->fontname);
printf("FullName: %s\n", param->fullname);
printf("FamilyName: Bedstead\n");
printf("Weight: Medium\n");
printf("OS2_WeightWidthSlopeOnly: 1\n");
printf("Copyright: Dedicated to the public domain\n");
printf("Version: 001.002\n");
printf("ItalicAngle: 0\n");
printf("UnderlinePosition: %d\n", -YPIX / 2);
printf("UnderlineWidth: %d\n", YPIX);
printf("OS2StrikeYPos: %d\n", 3 * YPIX);
printf("OS2StrikeYSize: %d\n", YPIX);
printf("Ascent: %d\n", 8 * YPIX);
printf("Descent: %d\n", 2 * YPIX);
/* Sub/Superscript are three by five pixels */
printf("OS2SubXSize: %d\n", YSIZE * YPIX * 3 / (XSIZE - 1));
printf("OS2SupXSize: %d\n", YSIZE * YPIX * 3 / (XSIZE - 1));
printf("OS2SubYSize: %d\n", YSIZE * YPIX * 5 / (YSIZE - 3));
printf("OS2SupYSize: %d\n", YSIZE * YPIX * 5 / (YSIZE - 3));
printf("OS2SubXOff: 0\n");
printf("OS2SupXOff: 0\n");
printf("OS2SubYOff: %d\n", 2 * YPIX);
printf("OS2SupYOff: %d\n", 2 * YPIX);
printf("FSType: 0\n");
printf("TTFWeight: 500\n");
printf("TTFWidth: %d\n", param->ttfwidth);
dopanose();
printf("OS2FamilyClass: %d\n", 0x080a);
printf("LayerCount: 2\n");
printf("Layer: 0 0 \"Back\" 1\n");
printf("Layer: 1 0 \"Fore\" 0\n");
printf("Encoding: UnicodeBmp\n");
printf("NameList: Adobe Glyph List\n");
printf("DisplaySize: -24\n");
printf("AntiAlias: 1\n");
printf("FitToEm: 1\n");
printf("BeginPrivate: 2\n");
printf(" StdHW 5 [%d]\n", YPIX);
printf(" StdVW 5 [%d]\n", XPIX);
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");
printf("Lookup: 1 0 0 \"salt: stylistic alternates\" {\"salt\"} "
"['salt' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n");
printf("Lookup: 1 0 0 \"ss01: SAA5051 forms\" {\"ss01\"} "
"['ss01' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n");
printf("OtfFeatName: 'ss01' 1033 \"SAA5051\"\n");
printf("Lookup: 1 0 0 \"ss02: SAA5052 forms\" {\"ss02\"} "
"['ss02' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n");
printf("OtfFeatName: 'ss02' 1033 \"SAA5052\"\n");
printf("Lookup: 1 0 0 \"ss04: SAA5054 forms\" {\"ss04\"} "
"['ss04' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n");
printf("OtfFeatName: 'ss04' 1033 \"SAA5054\"\n");
printf("Lookup: 3 0 0 \"aalt: all alternates\" {\"aalt\"} "
"['aalt' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n");
printf("Lookup: 257 0 0 \"palt: proportional metrics\" {\"palt\"} "
"['palt' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n");
printf("Lookup: 1 0 0 \"smcp: lower-case to small caps\" {\"smcp\"} "
"['smcp' ('latn' <'dflt'>)]\n");
printf("Lookup: 1 0 0 \"c2sc: upper-case to small caps\" {\"c2sc\"} "
"['c2sc' ('latn' <'dflt'>)]\n");
printf("BeginChars: %d %d\n", 65536 + extraglyphs, nglyphs);
extraglyphs = 0;
for (i = 0; i < nglyphs; i++) {
if (glyphs[i].name)
printf("\nStartChar: %s\n", glyphs[i].name);
else
printf("\nStartChar: uni%04X\n",
(unsigned)glyphs[i].unicode);
printf("Encoding: %d %d %d\n",
glyphs[i].unicode != -1 ? glyphs[i].unicode :
65536 + extraglyphs++, glyphs[i].unicode, i);
printf("Width: %d\n", XSIZE * XPIX);
printf("Flags: W\n");
printf("LayerCount: 2\n");
dolookups(&glyphs[i]);
if (glyphs[i].flags & MOS)
domosaic(glyphs[i].data[0],
(glyphs[i].data[0] & 0x20) != 0);
else
dochar(glyphs[i].data, glyphs[i].flags);
printf("EndChar\n");
}
printf("EndChars\n");
printf("EndSplineFont\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)
{
int i;
unsigned char cols = 0;
int dx = 0, dh = 0;
if (g->flags & MOS) 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; 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",
dx * XPIX, dh * XPIX);
}
static void
dolookups(struct glyph const *g)
{
char prefix[32];
size_t plen;
int i;
int const nglyphs = sizeof(glyphs) / sizeof(glyphs[0]);
if (g->name)
plen = sprintf(prefix, "%s.", g->name);
else
plen = sprintf(prefix, "uni%04X.", g->unicode);
assert(plen < 32);
/* Look for related glyphs */
for (i = 0; i < nglyphs; i++) {
if (glyphs[i].name &&
strncmp(prefix, glyphs[i].name, plen) == 0) {
if (strcmp(glyphs[i].name + plen, "alt") == 0)
printf("Substitution2: \"salt\" %s\n",
glyphs[i].name);
if (strcmp(glyphs[i].name + plen, "saa5051") == 0)
printf("Substitution2: \"ss01\" %s\n",
glyphs[i].name);
if (strcmp(glyphs[i].name + plen, "saa5052") == 0)
printf("Substitution2: \"ss02\" %s\n",
glyphs[i].name);
if (strcmp(glyphs[i].name + plen, "saa5054") == 0)
printf("Substitution2: \"ss04\" %s\n",
glyphs[i].name);
printf("AlternateSubs2: \"aalt\" %s\n",
glyphs[i].name);
}
}
if ((g->flags & SC))
printf("Substitution2: \"%s\" %c%ssc\n",
isupper((unsigned char)prefix[0]) ? "c2sc" : "smcp",
tolower((unsigned char)prefix[0]), prefix + 1);
dopalt(g);
}
typedef struct vec {
int x, y;
} vec;
typedef struct point {
struct point *next, *prev;
struct vec v;
} point;
#define MAXPOINTS (XSIZE * YSIZE * 20)
static point points[MAXPOINTS];
static int nextpoint;
static void
clearpath()
{
nextpoint = 0;
}
static void
moveto(unsigned x, unsigned y)
{
struct point *p = &points[nextpoint++];
p->v.x = x; p->v.y = y;
p->next = p->prev = NULL;
}
static void
lineto(unsigned x, unsigned y)
{
struct point *p = &points[nextpoint++];
p->v.x = x; p->v.y = y;
p->next = NULL;
p->prev = p - 1;
p->prev->next = p;
}
static void
closepath()
{
struct point *p = &points[nextpoint - 1];
while (p->prev) p--;
p->prev = points + nextpoint - 1;
points[nextpoint - 1].next = p;
}
static void
killpoint(point *p)
{
p->prev->next = p->next;
p->next->prev = p->prev;
p->next = p->prev = NULL;
}
static vec const zero = { 0, 0 };
static int
vec_eqp(vec v1, vec v2)
{
return v1.x == v2.x && v1.y == v2.y;
}
static vec
vec_sub(vec v1, vec v2)
{
vec ret;
ret.x = v1.x - v2.x; ret.y = v1.y - v2.y;
return ret;
}
static int
gcd(int a, int b)
{
int t;
while (b != 0) {
t = b;
b = a % b;
a = t;
}
return a;
}
/* Return the shortest representable vector parallel to the argument. */
static vec
vec_bearing(vec v)
{
vec ret;
int d = gcd(abs(v.x), abs(v.y));
if (d != 0) {
ret.x = v.x / d;
ret.y = v.y / d;
} else {
ret.x = 0;
ret.y = 0;
}
return ret;
}
/* If p is identical to its successor, remove p. */
static void
fix_identical(point *p)
{
if (!p->next) return;
if (vec_eqp(p->next->v, p->v))
killpoint(p);
}
/* Are a, b, and c distinct collinear points in that order? */
static int
vec_inline3(vec a, vec b, vec c)
{
return
vec_eqp(vec_bearing(vec_sub(b, a)), vec_bearing(vec_sub(c, b))) &&
!vec_eqp(vec_bearing(vec_sub(b, a)), zero);
}
/* Are a, b, c, and d distinct collinear points in that order? */
static int
vec_inline4(vec a, vec b, vec c, vec d)
{
return vec_inline3(a, b, c) && vec_inline3(b, c, d);
}
/* If p is on the line between its predecessor and successor, remove p. */
static void
fix_collinear(point *p)
{
if (!p->next) return;
if (vec_inline3(p->prev->v, p->v, p->next->v))
killpoint(p);
}
/* If p is the only point on its path, remove p. */
static void
fix_isolated(point *p)
{
if (p->next == p)
killpoint(p);
}
static int done_anything;
static void
fix_edges(point *a0, point *b0)
{
point *a1 = a0->next, *b1 = b0->next;
assert(a1->prev == a0); assert(b1->prev == b0);
assert(a0 != a1); assert(a0 != b0);
assert(a1 != b1); assert(b0 != b1);
if (vec_eqp(vec_bearing(vec_sub(a0->v, a1->v)),
vec_bearing(vec_sub(b1->v, b0->v))) &&
(vec_inline4(a0->v, b1->v, a1->v, b0->v) ||
vec_inline4(a0->v, b1->v, b0->v, a1->v) ||
vec_inline4(b1->v, a0->v, b0->v, a1->v) ||
vec_inline4(b1->v, a0->v, a1->v, b0->v) ||
vec_eqp(a0->v, b1->v) || vec_eqp(a1->v, b0->v))) {
a0->next = b1; b1->prev = a0;
b0->next = a1; a1->prev = b0;
fix_isolated(a0);
fix_identical(a0);
fix_collinear(b1);
fix_isolated(b0);
fix_identical(b0);
fix_collinear(a1);
done_anything = 1;
}
}
static void
clean_path()
{
int i, j;
do {
done_anything = 0;
for (i = 0; i < nextpoint; i++)
for (j = i+1; points[i].next && j < nextpoint; j++)
if (points[j].next)
fix_edges(&points[i], &points[j]);
} while (done_anything);
}
static void
emit_path()
{
int i, started = 0;
point *p, *p1;
for (i = 0; i < nextpoint; i++) {
p = &points[i];
if (p->next) {
if (!started) printf("Fore\nSplineSet\n");
started = 1;
do {
printf(" %g %g %s 1\n",
(double)p->v.x / SCALE,
(double)p->v.y / SCALE - 3*YPIX,
p == &points[i] && p->next ? "m" : "l");
p1 = p->next;
p->prev = p->next = NULL;
p = p1;
} while (p);
}
}
if (started) printf("EndSplineSet\n");
}
static void
blackpixel(int x, int y, int bl, int br, int tr, int tl)
{
x *= XPIX_S; y *= YPIX_S;
if (bl) moveto(x, y);
else { moveto(x+XQTR_S, y); lineto(x, y+YQTR_S); }
if (tl) lineto(x, y+YPIX_S);
else { lineto(x, y+YPIX_S-YQTR_S); lineto(x+XQTR_S, y+YPIX_S); }
if (tr) lineto(x+XPIX_S, y+YPIX_S);
else { lineto(x+XPIX_S-XQTR_S, y+YPIX_S);
lineto(x+XPIX_S, y+YPIX_S-YQTR_S); }
if (br) lineto(x+XPIX_S, y);
else { lineto(x+XPIX_S, y+YQTR_S); lineto(x+XPIX_S-XQTR_S, y); }
closepath();
}
static void
whitepixel(int x, int y, int bl, int br, int tr, int tl)
{
x *= XPIX_S; y *= YPIX_S;
if (bl) {
moveto(x, y); lineto(x, y+YPIX_S-YQTR_S);
if (br) { lineto(x+XPIX_S/2, y+YPIX_S/2-YQTR_S);
lineto(x+XQTR_S, y); }
else lineto(x+XPIX_S-XQTR_S, y);
closepath();
}
if (tl) {
moveto(x, y+YPIX_S); lineto(x+XPIX_S-XQTR_S, y+YPIX_S);
if (bl) { lineto(x+XPIX_S/2-XQTR_S, y+YPIX_S/2);
lineto(x, y+YPIX_S-YQTR_S); }
else lineto(x, y+YQTR_S);
closepath();
}
if (tr) {
moveto(x+XPIX_S, y+YPIX_S); lineto(x+XPIX_S, y+YQTR_S);
if (tl) { lineto(x+XPIX_S/2, y+YPIX_S/2+YQTR_S);
lineto(x+XPIX_S-XQTR_S, y+YPIX_S); }
else lineto(x+XQTR_S, y+YPIX_S);
closepath();
}
if (br) {
moveto(x+XPIX_S, y); lineto(x+XQTR_S, y);
if (tr) { lineto(x+XPIX_S/2+XQTR_S, y+YPIX_S/2);
lineto(x+XPIX_S, y+YQTR_S); }
else lineto(x+XPIX_S, y+YPIX_S-YQTR_S);
closepath();
}
}
void
dochar(char const data[YSIZE], unsigned flags)
{
int x, y;
#define GETPIX(x,y) (getpix(data, (x), (y), flags))
#define L GETPIX(x-1, y)
#define R GETPIX(x+1, y)
#define U GETPIX(x, y-1)
#define D GETPIX(x, y+1)
#define UL GETPIX(x-1, y-1)
#define UR GETPIX(x+1, y-1)
#define DL GETPIX(x-1, y+1)
#define DR GETPIX(x+1, y+1)
clearpath();
for (x = 0; x < XSIZE; x++) {
for (y = 0; y < YSIZE; y++) {
if (GETPIX(x, y)) {
bool tl, tr, bl, br;
/* Assume filled in */
tl = tr = bl = br = true;
/* Check for diagonals */
if ((UL && !U && !L) || (DR && !D && !R))
tr = bl = false;
if ((UR && !U && !R) || (DL && !D && !L))
tl = br = false;
/* Avoid odd gaps */
if (L || UL || U) tl = true;
if (R || UR || U) tr = true;
if (L || DL || D) bl = true;
if (R || DR || D) br = true;
blackpixel(x, YSIZE - y - 1, bl, br, tr, tl);
} else {
bool tl, tr, bl, br;
/* Assume clear */
tl = tr = bl = br = false;
/* white pixel -- just diagonals */
if (L && U && !UL) tl = true;
if (R && U && !UR) tr = true;
if (L && D && !DL) bl = true;
if (R && D && !DR) br = true;
whitepixel(x, YSIZE - y - 1, bl, br, tr, tl);
}
}
}
clean_path();
emit_path();
}
static void
tile(int x0, int y0, int x1, int y1)
{
x0 *= XPIX_S; y0 *= YPIX_S;
x1 *= XPIX_S; y1 *= YPIX_S;
moveto(x0, y0); lineto(x0, y1); lineto(x1, y1); lineto(x1, y0);
closepath();
}
static void
domosaic(unsigned code, bool sep)
{
clearpath();
if (code & 1) tile(0 + sep, 8 + sep, 3, 11);
if (code & 2) tile(3 + sep, 8 + sep, 6, 11);
if (code & 4) tile(0 + sep, 4 + sep, 3, 8);
if (code & 8) tile(3 + sep, 4 + sep, 6, 8);
if (code & 16) tile(0 + sep, 1 + sep, 3, 4);
if (code & 64) tile(3 + sep, 1 + sep, 6, 4);
clean_path();
emit_path();
}