diff --git a/Encodings.js b/Encodings.js
new file mode 100644
index 000000000..d32a399c8
--- /dev/null
+++ b/Encodings.js
@@ -0,0 +1,1552 @@
+
+var Encodings = {
+  ExpertEncoding: [
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "space",
+    "exclamsmall",
+    "Hungarumlautsmall",
+    null,
+    "dollaroldstyle",
+    "dollarsuperior",
+    "ampersandsmall",
+    "Acutesmall",
+    "parenleftsuperior",
+    "parenrightsuperior",
+    "twodotenleader",
+    "onedotenleader",
+    "comma",
+    "hyphen",
+    "period",
+    "fraction",
+    "zerooldstyle",
+    "oneoldstyle",
+    "twooldstyle",
+    "threeoldstyle",
+    "fouroldstyle",
+    "fiveoldstyle",
+    "sixoldstyle",
+    "sevenoldstyle",
+    "eightoldstyle",
+    "nineoldstyle",
+    "colon",
+    "semicolon",
+    "commasuperior",
+    "threequartersemdash",
+    "periodsuperior",
+    "questionsmall",
+    null,
+    "asuperior",
+    "bsuperior",
+    "centsuperior",
+    "dsuperior",
+    "esuperior",
+    null,
+    null,
+    null,
+    "isuperior",
+    null,
+    null,
+    "lsuperior",
+    "msuperior",
+    "nsuperior",
+    "osuperior",
+    null,
+    null,
+    "rsuperior",
+    "ssuperior",
+    "tsuperior",
+    null,
+    "ff",
+    "fi",
+    "fl",
+    "ffi",
+    "ffl",
+    "parenleftinferior",
+    null,
+    "parenrightinferior",
+    "Circumflexsmall",
+    "hyphensuperior",
+    "Gravesmall",
+    "Asmall",
+    "Bsmall",
+    "Csmall",
+    "Dsmall",
+    "Esmall",
+    "Fsmall",
+    "Gsmall",
+    "Hsmall",
+    "Ismall",
+    "Jsmall",
+    "Ksmall",
+    "Lsmall",
+    "Msmall",
+    "Nsmall",
+    "Osmall",
+    "Psmall",
+    "Qsmall",
+    "Rsmall",
+    "Ssmall",
+    "Tsmall",
+    "Usmall",
+    "Vsmall",
+    "Wsmall",
+    "Xsmall",
+    "Ysmall",
+    "Zsmall",
+    "colonmonetary",
+    "onefitted",
+    "rupiah",
+    "Tildesmall",
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "exclamdownsmall",
+    "centoldstyle",
+    "Lslashsmall",
+    null,
+    null,
+    "Scaronsmall",
+    "Zcaronsmall",
+    "Dieresissmall",
+    "Brevesmall",
+    "Caronsmall",
+    null,
+    "Dotaccentsmall",
+    null,
+    null,
+    "Macronsmall",
+    null,
+    null,
+    "figuredash",
+    "hypheninferior",
+    null,
+    null,
+    "Ogoneksmall",
+    "Ringsmall",
+    "Cedillasmall",
+    null,
+    null,
+    null,
+    "onequarter",
+    "onehalf",
+    "threequarters",
+    "questiondownsmall",
+    "oneeighth",
+    "threeeighths",
+    "fiveeighths",
+    "seveneighths",
+    "onethird",
+    "twothirds",
+    null,
+    null,
+    "zerosuperior",
+    "onesuperior",
+    "twosuperior",
+    "threesuperior",
+    "foursuperior",
+    "fivesuperior",
+    "sixsuperior",
+    "sevensuperior",
+    "eightsuperior",
+    "ninesuperior",
+    "zeroinferior",
+    "oneinferior",
+    "twoinferior",
+    "threeinferior",
+    "fourinferior",
+    "fiveinferior",
+    "sixinferior",
+    "seveninferior",
+    "eightinferior",
+    "nineinferior",
+    "centinferior",
+    "dollarinferior",
+    "periodinferior",
+    "commainferior",
+    "Agravesmall",
+    "Aacutesmall",
+    "Acircumflexsmall",
+    "Atildesmall",
+    "Adieresissmall",
+    "Aringsmall",
+    "AEsmall",
+    "Ccedillasmall",
+    "Egravesmall",
+    "Eacutesmall",
+    "Ecircumflexsmall",
+    "Edieresissmall",
+    "Igravesmall",
+    "Iacutesmall",
+    "Icircumflexsmall",
+    "Idieresissmall",
+    "Ethsmall",
+    "Ntildesmall",
+    "Ogravesmall",
+    "Oacutesmall",
+    "Ocircumflexsmall",
+    "Otildesmall",
+    "Odieresissmall",
+    "OEsmall",
+    "Oslashsmall",
+    "Ugravesmall",
+    "Uacutesmall",
+    "Ucircumflexsmall",
+    "Udieresissmall",
+    "Yacutesmall",
+    "Thornsmall",
+    "Ydieresissmall"
+  ],
+  MacExpertEncoding: [
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "space",
+    "exclamsmall",
+    "Hungarumlautsmall",
+    "centoldstyle",
+    "dollaroldstyle",
+    "dollarsuperior",
+    "ampersandsmall",
+    "Acutesmall",
+    "parenleftsuperior",
+    "parenrightsuperior",
+    "twodotenleader",
+    "onedotenleader",
+    "comma",
+    "hyphen",
+    "period",
+    "fraction",
+    "zerooldstyle",
+    "oneoldstyle",
+    "twooldstyle",
+    "threeoldstyle",
+    "fouroldstyle",
+    "fiveoldstyle",
+    "sixoldstyle",
+    "sevenoldstyle",
+    "eightoldstyle",
+    "nineoldstyle",
+    "colon",
+    "semicolon",
+    null,
+    "threequartersemdash",
+    null,
+    "questionsmall",
+    null,
+    null,
+    null,
+    null,
+    "Ethsmall",
+    null,
+    null,
+    "onequarter",
+    "onehalf",
+    "threequarters",
+    "oneeighth",
+    "threeeighths",
+    "fiveeighths",
+    "seveneighths",
+    "onethird",
+    "twothirds",
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "ff",
+    "fi",
+    "fl",
+    "ffi",
+    "ffl",
+    "parenleftinferior",
+    null,
+    "parenrightinferior",
+    "Circumflexsmall",
+    "hypheninferior",
+    "Gravesmall",
+    "Asmall",
+    "Bsmall",
+    "Csmall",
+    "Dsmall",
+    "Esmall",
+    "Fsmall",
+    "Gsmall",
+    "Hsmall",
+    "Ismall",
+    "Jsmall",
+    "Ksmall",
+    "Lsmall",
+    "Msmall",
+    "Nsmall",
+    "Osmall",
+    "Psmall",
+    "Qsmall",
+    "Rsmall",
+    "Ssmall",
+    "Tsmall",
+    "Usmall",
+    "Vsmall",
+    "Wsmall",
+    "Xsmall",
+    "Ysmall",
+    "Zsmall",
+    "colonmonetary",
+    "onefitted",
+    "rupiah",
+    "Tildesmall",
+    null,
+    null,
+    "asuperior",
+    "centsuperior",
+    null,
+    null,
+    null,
+    null,
+    "Aacutesmall",
+    "Agravesmall",
+    "Acircumflexsmall",
+    "Adieresissmall",
+    "Atildesmall",
+    "Aringsmall",
+    "Ccedillasmall",
+    "Eacutesmall",
+    "Egravesmall",
+    "Ecircumflexsmall",
+    "Edieresissmall",
+    "Iacutesmall",
+    "Igravesmall",
+    "Icircumflexsmall",
+    "Idieresissmall",
+    "Ntildesmall",
+    "Oacutesmall",
+    "Ogravesmall",
+    "Ocircumflexsmall",
+    "Odieresissmall",
+    "Otildesmall",
+    "Uacutesmall",
+    "Ugravesmall",
+    "Ucircumflexsmall",
+    "Udieresissmall",
+    null,
+    "eightsuperior",
+    "fourinferior",
+    "threeinferior",
+    "sixinferior",
+    "eightinferior",
+    "seveninferior",
+    "Scaronsmall",
+    null,
+    "centinferior",
+    "twoinferior",
+    null,
+    "Dieresissmall",
+    null,
+    "Caronsmall",
+    "osuperior",
+    "fiveinferior",
+    null,
+    "commainferior",
+    "periodinferior",
+    "Yacutesmall",
+    null,
+    "dollarinferior",
+    null,
+    null,
+    "Thornsmall",
+    null,
+    "nineinferior",
+    "zeroinferior",
+    "Zcaronsmall",
+    "AEsmall",
+    "Oslashsmall",
+    "questiondownsmall",
+    "oneinferior",
+    "Lslashsmall",
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "Cedillasmall",
+    null,
+    null,
+    null,
+    null,
+    null,
+    "OEsmall",
+    "figuredash",
+    "hyphensuperior",
+    null,
+    null,
+    null,
+    null,
+    "exclamdownsmall",
+    null,
+    "Ydieresissmall",
+    null,
+    "onesuperior",
+    "twosuperior",
+    "threesuperior",
+    "foursuperior",
+    "fivesuperior",
+    "sixsuperior",
+    "sevensuperior",
+    "ninesuperior",
+    "zerosuperior",
+    null,
+    "esuperior",
+    "rsuperior",
+    "tsuperior",
+    null,
+    null,
+    "isuperior",
+    "ssuperior",
+    "dsuperior",
+    null,
+    null,
+    null,
+    null,
+    null,
+    "lsuperior",
+    "Ogoneksmall",
+    "Brevesmall",
+    "Macronsmall",
+    "bsuperior",
+    "nsuperior",
+    "msuperior",
+    "commasuperior",
+    "periodsuperior",
+    "Dotaccentsmall",
+    "Ringsmall",
+    null,
+    null,
+    null,
+    null
+  ],
+  MacRomanEncoding: [
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "space",
+    "exclam",
+    "quotedbl",
+    "numbersign",
+    "dollar",
+    "percent",
+    "ampersand",
+    "quotesingle",
+    "parenleft",
+    "parenright",
+    "asterisk",
+    "plus",
+    "comma",
+    "hyphen",
+    "period",
+    "slash",
+    "zero",
+    "one",
+    "two",
+    "three",
+    "four",
+    "five",
+    "six",
+    "seven",
+    "eight",
+    "nine",
+    "colon",
+    "semicolon",
+    "less",
+    "equal",
+    "greater",
+    "question",
+    "at",
+    "A",
+    "B",
+    "C",
+    "D",
+    "E",
+    "F",
+    "G",
+    "H",
+    "I",
+    "J",
+    "K",
+    "L",
+    "M",
+    "N",
+    "O",
+    "P",
+    "Q",
+    "R",
+    "S",
+    "T",
+    "U",
+    "V",
+    "W",
+    "X",
+    "Y",
+    "Z",
+    "bracketleft",
+    "backslash",
+    "bracketright",
+    "asciicircum",
+    "underscore",
+    "grave",
+    "a",
+    "b",
+    "c",
+    "d",
+    "e",
+    "f",
+    "g",
+    "h",
+    "i",
+    "j",
+    "k",
+    "l",
+    "m",
+    "n",
+    "o",
+    "p",
+    "q",
+    "r",
+    "s",
+    "t",
+    "u",
+    "v",
+    "w",
+    "x",
+    "y",
+    "z",
+    "braceleft",
+    "bar",
+    "braceright",
+    "asciitilde",
+    null,
+    "Adieresis",
+    "Aring",
+    "Ccedilla",
+    "Eacute",
+    "Ntilde",
+    "Odieresis",
+    "Udieresis",
+    "aacute",
+    "agrave",
+    "acircumflex",
+    "adieresis",
+    "atilde",
+    "aring",
+    "ccedilla",
+    "eacute",
+    "egrave",
+    "ecircumflex",
+    "edieresis",
+    "iacute",
+    "igrave",
+    "icircumflex",
+    "idieresis",
+    "ntilde",
+    "oacute",
+    "ograve",
+    "ocircumflex",
+    "odieresis",
+    "otilde",
+    "uacute",
+    "ugrave",
+    "ucircumflex",
+    "udieresis",
+    "dagger",
+    "degree",
+    "cent",
+    "sterling",
+    "section",
+    "bullet",
+    "paragraph",
+    "germandbls",
+    "registered",
+    "copyright",
+    "trademark",
+    "acute",
+    "dieresis",
+    "notequal",
+    "AE",
+    "Oslash",
+    "infinity",
+    "plusminus",
+    "lessequal",
+    "greaterequal",
+    "yen",
+    "mu",
+    "partialdiff",
+    "summation",
+    "product",
+    "pi",
+    "integral",
+    "ordfeminine",
+    "ordmasculine",
+    "Omega",
+    "ae",
+    "oslash",
+    "questiondown",
+    "exclamdown",
+    "logicalnot",
+    "radical",
+    "florin",
+    "approxequal",
+    "Delta",
+    "guillemotleft",
+    "guillemotright",
+    "ellipsis",
+    "space",
+    "Agrave",
+    "Atilde",
+    "Otilde",
+    "OE",
+    "oe",
+    "endash",
+    "emdash",
+    "quotedblleft",
+    "quotedblright",
+    "quoteleft",
+    "quoteright",
+    "divide",
+    "lozenge",
+    "ydieresis",
+    "Ydieresis",
+    "fraction",
+    "currency",
+    "guilsinglleft",
+    "guilsinglright",
+    "fi",
+    "fl",
+    "daggerdbl",
+    "periodcentered",
+    "quotesinglbase",
+    "quotedblbase",
+    "perthousand",
+    "Acircumflex",
+    "Ecircumflex",
+    "Aacute",
+    "Edieresis",
+    "Egrave",
+    "Iacute",
+    "Icircumflex",
+    "Idieresis",
+    "Igrave",
+    "Oacute",
+    "Ocircumflex",
+    "apple",
+    "Ograve",
+    "Uacute",
+    "Ucircumflex",
+    "Ugrave",
+    "dotlessi",
+    "circumflex",
+    "tilde",
+    "macron",
+    "breve",
+    "dotaccent",
+    "ring",
+    "cedilla",
+    "hungarumlaut",
+    "ogonek",
+    "caron"
+  ],
+  StandardEncoding: [
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "space",
+    "exclam",
+    "quotedbl",
+    "numbersign",
+    "dollar",
+    "percent",
+    "ampersand",
+    "quoteright",
+    "parenleft",
+    "parenright",
+    "asterisk",
+    "plus",
+    "comma",
+    "hyphen",
+    "period",
+    "slash",
+    "zero",
+    "one",
+    "two",
+    "three",
+    "four",
+    "five",
+    "six",
+    "seven",
+    "eight",
+    "nine",
+    "colon",
+    "semicolon",
+    "less",
+    "equal",
+    "greater",
+    "question",
+    "at",
+    "A",
+    "B",
+    "C",
+    "D",
+    "E",
+    "F",
+    "G",
+    "H",
+    "I",
+    "J",
+    "K",
+    "L",
+    "M",
+    "N",
+    "O",
+    "P",
+    "Q",
+    "R",
+    "S",
+    "T",
+    "U",
+    "V",
+    "W",
+    "X",
+    "Y",
+    "Z",
+    "bracketleft",
+    "backslash",
+    "bracketright",
+    "asciicircum",
+    "underscore",
+    "quoteleft",
+    "a",
+    "b",
+    "c",
+    "d",
+    "e",
+    "f",
+    "g",
+    "h",
+    "i",
+    "j",
+    "k",
+    "l",
+    "m",
+    "n",
+    "o",
+    "p",
+    "q",
+    "r",
+    "s",
+    "t",
+    "u",
+    "v",
+    "w",
+    "x",
+    "y",
+    "z",
+    "braceleft",
+    "bar",
+    "braceright",
+    "asciitilde",
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "exclamdown",
+    "cent",
+    "sterling",
+    "fraction",
+    "yen",
+    "florin",
+    "section",
+    "currency",
+    "quotesingle",
+    "quotedblleft",
+    "guillemotleft",
+    "guilsinglleft",
+    "guilsinglright",
+    "fi",
+    "fl",
+    null,
+    "endash",
+    "dagger",
+    "daggerdbl",
+    "periodcentered",
+    null,
+    "paragraph",
+    "bullet",
+    "quotesinglbase",
+    "quotedblbase",
+    "quotedblright",
+    "guillemotright",
+    "ellipsis",
+    "perthousand",
+    null,
+    "questiondown",
+    null,
+    "grave",
+    "acute",
+    "circumflex",
+    "tilde",
+    "macron",
+    "breve",
+    "dotaccent",
+    "dieresis",
+    null,
+    "ring",
+    "cedilla",
+    null,
+    "hungarumlaut",
+    "ogonek",
+    "caron",
+    "emdash",
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "AE",
+    null,
+    "ordfeminine",
+    null,
+    null,
+    null,
+    null,
+    "Lslash",
+    "Oslash",
+    "OE",
+    "ordmasculine",
+    null,
+    null,
+    null,
+    null,
+    null,
+    "ae",
+    null,
+    null,
+    null,
+    "dotlessi",
+    null,
+    null,
+    "lslash",
+    "oslash",
+    "oe",
+    "germandbls",
+    null,
+    null,
+    null,
+    null
+  ],
+  WinAnsiEncoding: [
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "space",
+    "exclam",
+    "quotedbl",
+    "numbersign",
+    "dollar",
+    "percent",
+    "ampersand",
+    "quotesingle",
+    "parenleft",
+    "parenright",
+    "asterisk",
+    "plus",
+    "comma",
+    "hyphen",
+    "period",
+    "slash",
+    "zero",
+    "one",
+    "two",
+    "three",
+    "four",
+    "five",
+    "six",
+    "seven",
+    "eight",
+    "nine",
+    "colon",
+    "semicolon",
+    "less",
+    "equal",
+    "greater",
+    "question",
+    "at",
+    "A",
+    "B",
+    "C",
+    "D",
+    "E",
+    "F",
+    "G",
+    "H",
+    "I",
+    "J",
+    "K",
+    "L",
+    "M",
+    "N",
+    "O",
+    "P",
+    "Q",
+    "R",
+    "S",
+    "T",
+    "U",
+    "V",
+    "W",
+    "X",
+    "Y",
+    "Z",
+    "bracketleft",
+    "backslash",
+    "bracketright",
+    "asciicircum",
+    "underscore",
+    "grave",
+    "a",
+    "b",
+    "c",
+    "d",
+    "e",
+    "f",
+    "g",
+    "h",
+    "i",
+    "j",
+    "k",
+    "l",
+    "m",
+    "n",
+    "o",
+    "p",
+    "q",
+    "r",
+    "s",
+    "t",
+    "u",
+    "v",
+    "w",
+    "x",
+    "y",
+    "z",
+    "braceleft",
+    "bar",
+    "braceright",
+    "asciitilde",
+    "bullet",
+    "Euro",
+    "bullet",
+    "quotesinglbase",
+    "florin",
+    "quotedblbase",
+    "ellipsis",
+    "dagger",
+    "daggerdbl",
+    "circumflex",
+    "perthousand",
+    "Scaron",
+    "guilsinglleft",
+    "OE",
+    "bullet",
+    "Zcaron",
+    "bullet",
+    "bullet",
+    "quoteleft",
+    "quoteright",
+    "quotedblleft",
+    "quotedblright",
+    "bullet",
+    "endash",
+    "emdash",
+    "tilde",
+    "trademark",
+    "scaron",
+    "guilsinglright",
+    "oe",
+    "bullet",
+    "zcaron",
+    "Ydieresis",
+    "space",
+    "exclamdown",
+    "cent",
+    "sterling",
+    "currency",
+    "yen",
+    "brokenbar",
+    "section",
+    "dieresis",
+    "copyright",
+    "ordfeminine",
+    "guillemotleft",
+    "logicalnot",
+    "hyphen",
+    "registered",
+    "macron",
+    "degree",
+    "plusminus",
+    "twosuperior",
+    "threesuperior",
+    "acute",
+    "mu",
+    "paragraph",
+    "periodcentered",
+    "cedilla",
+    "onesuperior",
+    "ordmasculine",
+    "guillemotright",
+    "onequarter",
+    "onehalf",
+    "threequarters",
+    "questiondown",
+    "Agrave",
+    "Aacute",
+    "Acircumflex",
+    "Atilde",
+    "Adieresis",
+    "Aring",
+    "AE",
+    "Ccedilla",
+    "Egrave",
+    "Eacute",
+    "Ecircumflex",
+    "Edieresis",
+    "Igrave",
+    "Iacute",
+    "Icircumflex",
+    "Idieresis",
+    "Eth",
+    "Ntilde",
+    "Ograve",
+    "Oacute",
+    "Ocircumflex",
+    "Otilde",
+    "Odieresis",
+    "multiply",
+    "Oslash",
+    "Ugrave",
+    "Uacute",
+    "Ucircumflex",
+    "Udieresis",
+    "Yacute",
+    "Thorn",
+    "germandbls",
+    "agrave",
+    "aacute",
+    "acircumflex",
+    "atilde",
+    "adieresis",
+    "aring",
+    "ae",
+    "ccedilla",
+    "egrave",
+    "eacute",
+    "ecircumflex",
+    "edieresis",
+    "igrave",
+    "iacute",
+    "icircumflex",
+    "idieresis",
+    "eth",
+    "ntilde",
+    "ograve",
+    "oacute",
+    "ocircumflex",
+    "otilde",
+    "odieresis",
+    "divide",
+    "oslash",
+    "ugrave",
+    "uacute",
+    "ucircumflex",
+    "udieresis",
+    "yacute",
+    "thorn",
+    "ydieresis"
+  ],
+  zapfDingbatsEncoding: [
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "space",
+    "a1",
+    "a2",
+    "a202",
+    "a3",
+    "a4",
+    "a5",
+    "a119",
+    "a118",
+    "a117",
+    "a11",
+    "a12",
+    "a13",
+    "a14",
+    "a15",
+    "a16",
+    "a105",
+    "a17",
+    "a18",
+    "a19",
+    "a20",
+    "a21",
+    "a22",
+    "a23",
+    "a24",
+    "a25",
+    "a26",
+    "a27",
+    "a28",
+    "a6",
+    "a7",
+    "a8",
+    "a9",
+    "a10",
+    "a29",
+    "a30",
+    "a31",
+    "a32",
+    "a33",
+    "a34",
+    "a35",
+    "a36",
+    "a37",
+    "a38",
+    "a39",
+    "a40",
+    "a41",
+    "a42",
+    "a43",
+    "a44",
+    "a45",
+    "a46",
+    "a47",
+    "a48",
+    "a49",
+    "a50",
+    "a51",
+    "a52",
+    "a53",
+    "a54",
+    "a55",
+    "a56",
+    "a57",
+    "a58",
+    "a59",
+    "a60",
+    "a61",
+    "a62",
+    "a63",
+    "a64",
+    "a65",
+    "a66",
+    "a67",
+    "a68",
+    "a69",
+    "a70",
+    "a71",
+    "a72",
+    "a73",
+    "a74",
+    "a203",
+    "a75",
+    "a204",
+    "a76",
+    "a77",
+    "a78",
+    "a79",
+    "a81",
+    "a82",
+    "a83",
+    "a84",
+    "a97",
+    "a98",
+    "a99",
+    "a100",
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    null,
+    "a101",
+    "a102",
+    "a103",
+    "a104",
+    "a106",
+    "a107",
+    "a108",
+    "a112",
+    "a111",
+    "a110",
+    "a109",
+    "a120",
+    "a121",
+    "a122",
+    "a123",
+    "a124",
+    "a125",
+    "a126",
+    "a127",
+    "a128",
+    "a129",
+    "a130",
+    "a131",
+    "a132",
+    "a133",
+    "a134",
+    "a135",
+    "a136",
+    "a137",
+    "a138",
+    "a139",
+    "a140",
+    "a141",
+    "a142",
+    "a143",
+    "a144",
+    "a145",
+    "a146",
+    "a147",
+    "a148",
+    "a149",
+    "a150",
+    "a151",
+    "a152",
+    "a153",
+    "a154",
+    "a155",
+    "a156",
+    "a157",
+    "a158",
+    "a159",
+    "a160",
+    "a161",
+    "a163",
+    "a164",
+    "a196",
+    "a165",
+    "a192",
+    "a166",
+    "a167",
+    "a168",
+    "a169",
+    "a170",
+    "a171",
+    "a172",
+    "a173",
+    "a162",
+    "a174",
+    "a175",
+    "a176",
+    "a177",
+    "a178",
+    "a179",
+    "a193",
+    "a180",
+    "a199",
+    "a181",
+    "a200",
+    "a182",
+    null,
+    "a201",
+    "a183",
+    "a184",
+    "a197",
+    "a185",
+    "a194",
+    "a198",
+    "a186",
+    "a195",
+    "a187",
+    "a188",
+    "a189",
+    "a190",
+    "a191",
+    null
+  ]
+};
+
diff --git a/cffStandardStrings.js b/cffStandardStrings.js
new file mode 100644
index 000000000..8977cd8f2
--- /dev/null
+++ b/cffStandardStrings.js
@@ -0,0 +1,689 @@
+var CFFStrings = [
+  ".notdef", 
+  "space",
+  "exclam",
+  "quotedbl",
+  "numbersign",
+  "dollar",
+  "percent",
+  "ampersand",
+  "quoteright",
+  "parenleft",
+  "parenright",
+  "asterisk",
+  "plus",
+  "comma",
+  "hyphen",
+  "period",
+  "slash",
+  "zero",
+  "one",
+  "two",
+  "three",
+  "four",
+  "five",
+  "six",
+  "seven",
+  "eight",
+  "nine",
+  "colon",
+  "semicolon",
+  "less",
+  "equal",
+  "greater",
+  "question",
+  "at",
+  "A",
+  "B",
+  "C",
+  "D",
+  "E",
+  "F",
+  "G",
+  "H",
+  "I",
+  "J",
+  "K",
+  "L",
+  "M",
+  "N",
+  "O",
+  "P",
+  "Q",
+  "R",
+  "S",
+  "T",
+  "U",
+  "V",
+  "W",
+  "X",
+  "Y",
+  "Z",
+  "bracketleft",
+  "backslash",
+  "bracketright",
+  "asciicircum",
+  "underscore",
+  "quoteleft",
+  "a",
+  "b",
+  "c",
+  "d",
+  "e",
+  "f",
+  "g",
+  "h",
+  "i",
+  "j",
+  "k",
+  "l",
+  "m",
+  "n",
+  "o",
+  "p",
+  "q",
+  "r",
+  "s",
+  "t",
+  "u",
+  "v",
+  "w",
+  "x",
+  "y",
+  "z",
+  "braceleft",
+  "bar",
+  "braceright",
+  "asciitilde",
+  "exclamdown",
+  "cent",
+  "sterling",
+  "fraction",
+  "yen",
+  "florin",
+  "section",
+  "currency",
+  "quotesingle",
+  "quotedblleft",
+  "guillemotleft",
+  "guilsinglleft",
+  "guilsinglright",
+  "fi",
+  "fl",
+  "endash",
+  "dagger",
+  "daggerdbl",
+  "periodcentered",
+  "paragraph",
+  "bullet",
+  "quotesinglbase",
+  "quotedblbase",
+  "quotedblright",
+  "guillemotright",
+  "ellipsis",
+  "perthousand",
+  "questiondown",
+  "grave",
+  "acute",
+  "circumflex",
+  "tilde",
+  "macron",
+  "breve",
+  "dotaccent",
+  "dieresis",
+  "ring",
+  "cedilla",
+  "hungarumlaut",
+  "ogonek",
+  "caron",
+  "emdash",
+  "AE",
+  "ordfeminine",
+  "Lslash",
+  "Oslash",
+  "OE",
+  "ordmasculine",
+  "ae",
+  "dotlessi",
+  "lslash",
+  "oslash",
+  "oe",
+  "germandbls",
+  "onesuperior",
+  "logicalnot",
+  "mu",
+  "trademark",
+  "Eth",
+  "onehalf",
+  "plusminus",
+  "Thorn",
+  "onequarter",
+  "divide",
+  "brokenbar",
+  "degree",
+  "thorn",
+  "threequarters",
+  "twosuperior",
+  "registered",
+  "minus",
+  "eth",
+  "multiply",
+  "threesuperior",
+  "copyright",
+  "Aacute",
+  "Acircumflex",
+  "Adieresis",
+  "Agrave",
+  "Aring",
+  "Atilde",
+  "Ccedilla",
+  "Eacute",
+  "Ecircumflex",
+  "Edieresis",
+  "Egrave",
+  "Iacute",
+  "Icircumflex",
+  "Idieresis",
+  "Igrave",
+  "Ntilde",
+  "Oacute",
+  "Ocircumflex",
+  "Odieresis",
+  "Ograve",
+  "Otilde",
+  "Scaron",
+  "Uacute",
+  "Ucircumflex",
+  "Udieresis",
+  "Ugrave",
+  "Yacute",
+  "Ydieresis",
+  "Zcaron",
+  "aacute",
+  "acircumflex",
+  "adieresis",
+  "agrave",
+  "aring",
+  "atilde",
+  "ccedilla",
+  "eacute",
+  "ecircumflex",
+  "edieresis",
+  "egrave",
+  "iacute",
+  "icircumflex",
+  "idieresis",
+  "igrave",
+  "ntilde",
+  "oacute",
+  "ocircumflex",
+  "odieresis",
+  "ograve",
+  "otilde",
+  "scaron",
+  "uacute",
+  "ucircumflex",
+  "udieresis",
+  "ugrave",
+  "yacute",
+  "ydieresis",
+  "zcaron",
+  "exclamsmall",
+  "Hungarumlautsmall",
+  "dollaroldstyle",
+  "dollarsuperior",
+  "ampersandsmall",
+  "Acutesmall",
+  "parenleftsuperior",
+  "parenrightsuperior",
+  "266 ff",
+  "onedotenleader",
+  "zerooldstyle",
+  "oneoldstyle",
+  "twooldstyle",
+  "threeoldstyle",
+  "fouroldstyle",
+  "fiveoldstyle",
+  "sixoldstyle",
+  "sevenoldstyle",
+  "eightoldstyle",
+  "nineoldstyle",
+  "commasuperior",
+  "threequartersemdash",
+  "periodsuperior",
+  "questionsmall",
+  "asuperior",
+  "bsuperior",
+  "centsuperior",
+  "dsuperior",
+  "esuperior",
+  "isuperior",
+  "lsuperior",
+  "msuperior",
+  "nsuperior",
+  "osuperior",
+  "rsuperior",
+  "ssuperior",
+  "tsuperior",
+  "ff",
+  "ffi",
+  "ffl",
+  "parenleftinferior",
+  "parenrightinferior",
+  "Circumflexsmall",
+  "hyphensuperior",
+  "Gravesmall",
+  "Asmall",
+  "Bsmall",
+  "Csmall",
+  "Dsmall",
+  "Esmall",
+  "Fsmall",
+  "Gsmall",
+  "Hsmall",
+  "Ismall",
+  "Jsmall",
+  "Ksmall",
+  "Lsmall",
+  "Msmall",
+  "Nsmall",
+  "Osmall",
+  "Psmall",
+  "Qsmall",
+  "Rsmall",
+  "Ssmall",
+  "Tsmall",
+  "Usmall",
+  "Vsmall",
+  "Wsmall",
+  "Xsmall",
+  "Ysmall",
+  "Zsmall",
+  "colonmonetary",
+  "onefitted",
+  "rupiah",
+  "Tildesmall",
+  "exclamdownsmall",
+  "centoldstyle",
+  "Lslashsmall",
+  "Scaronsmall",
+  "Zcaronsmall",
+  "Dieresissmall",
+  "Brevesmall",
+  "Caronsmall",
+  "Dotaccentsmall",
+  "Macronsmall",
+  "figuredash",
+  "hypheninferior",
+  "Ogoneksmall",
+  "Ringsmall",
+  "Cedillasmall",
+  "questiondownsmall",
+  "oneeighth",
+  "threeeighths",
+  "fiveeighths",
+  "seveneighths",
+  "onethird",
+  "twothirds",
+  "zerosuperior",
+  "foursuperior",
+  "fivesuperior",
+  "sixsuperior",
+  "sevensuperior",
+  "eightsuperior",
+  "ninesuperior",
+  "zeroinferior",
+  "oneinferior",
+  "twoinferior",
+  "threeinferior",
+  "fourinferior",
+  "fiveinferior",
+  "sixinferior",
+  "seveninferior",
+  "eightinferior",
+  "nineinferior",
+  "centinferior",
+  "dollarinferior",
+  "periodinferior",
+  "commainferior",
+  "Agravesmall",
+  "Aacutesmall",
+  "Acircumflexsmall",
+  "Atildesmall",
+  "Adieresissmall",
+  "Aringsmall",
+  "AEsmall",
+  "Ccedillasmall",
+  "Egravesmall",
+  "Eacutesmall",
+  "Ecircumflexsmall",
+  "Edieresissmall",
+  "Igravesmall",
+  "Iacutesmall",
+  "Icircumflexsmall",
+  "Idieresissmall",
+  "Ethsmall",
+  "Ntildesmall",
+  "Ogravesmall",
+  "Oacutesmall",
+  "Ocircumflexsmall",
+  "Otildesmall",
+  "Odieresissmall",
+  "OEsmall",
+  "Oslashsmall",
+  "Ugravesmall",
+  "Uacutesmall",
+  "Ucircumflexsmall",
+  "Udieresissmall",
+  "Yacutesmall",
+  "Thornsmall",
+  "Ydieresissmall",
+  "001.000",
+  "001.001",
+  "001.002",
+  "001.003",
+  "Black",
+  "Bold",
+  "Book",
+  "Light",
+  "Medium",
+  "Regular",
+  "Roman",
+  "Semibold"
+];
+
+var CFFEncodingMap = {
+  "0": "-reserved-",
+  "1": "hstem",
+  "2": "-reserved-",
+  "3": "vstem",
+  "4": "vmoveto",
+  "5": "rlineto",
+  "6": "hlineto",
+  "7": "vlineto",
+  "8": "rrcurveto",
+  "9": "-reserved-",
+  "10": "callsubr",
+  "11": "return",
+  "12": {
+    "3": "and",
+    "4": "or",
+    "5": "not",
+    "9": "abs",
+    "10": "add",
+    "11": "div",
+    "12": "sub",
+    "14": "neg",
+    "15": "eq",
+    "18": "drop",
+    "20": "put",
+    "21": "get",
+    "22": "ifelse",
+    "23": "random",
+    "24": "mul",
+    "26": "sqrt",
+    "27": "dup",
+    "28": "exch",
+    "29": "index",
+    "30": "roll",
+    "34": "hflex",
+    "35": "flex",
+    "36": "hflex1",
+    "37": "flex1"
+  },
+  "13": "-reserved-",
+  "14": "endchar",
+  "15": "-reserved-",
+  "16": "-reserved-",
+  "17": "-reserved-",
+  "18": "hstemhm",
+  "19": "hintmask",
+  "20": "cntrmask",
+  "21": "rmoveto",
+  "22": "hmoveto",
+  "23": "vstemhm",
+  "24": "rcurveline",
+  "25": "rlivecurve",
+  "26": "vvcurveto",
+  "27": "hhcurveto",
+  "29": "callgsubr",
+  "30": "vhcurveto",
+  "31": "hvcurveto"
+};
+
+var CFFDictDataMap = {
+  "0": {
+    name: "version",
+    operand: "SID"
+  },
+  "1": {
+    name: "Notice",
+    operand: "SID"
+  },
+  "2": {
+    name: "FullName",
+    operand: "SID"
+  },
+  "3": {
+    name: "FamilyName",
+    operand: "SID"
+  },
+  "4": {
+    name: "Weight",
+    operand: "SID"
+  },
+  "5": {
+    name: "FontBBox",
+    operand: [0, 0, 0, 0]
+  },
+  "6": {
+    name: "BlueValues"
+  },
+  "7": {
+    name: "OtherBlues"
+  },
+  "8": {
+    name: "FamilyBlues"
+  },
+  "9": {
+    name: "FamilyOtherBlues"
+  },
+  "10": {
+    name: "StdHW"
+  }, 
+  "11": {
+    name: "StdVW"
+  },
+  "12": {
+    "0": {
+      name: "Copyright",
+      operand: "SID"
+    },
+    "1": {
+      name: "IsFixedPitch",
+      operand: false
+    },
+    "2": {
+      name: "ItalicAngle",
+      operand: 0
+    },
+    "3": {
+      name: "UnderlinePosition",
+      operand: -100
+    },
+    "4": {
+      name: "UnderlineThickness",
+      operand: 50
+    },
+    "5": {
+      name: "PaintType",
+      operand: 0
+    },
+    "6": {
+      name: "CharstringType",
+      operand: 2
+    },
+    "7": {
+      name: "FontMatrix",
+      operand: [0.001, 0, 0, 0.001, 0 ,0]
+    },
+    "8": {
+      name: "StrokeWidth",
+      operand: 0
+    },
+    "9": {
+      name: "BlueScale"
+    },
+    "10": {
+      name: "BlueShift"
+    },
+    "11": {
+      name: "BlueFuzz"
+    },
+    "12": {
+      name: "StemSnapH"
+    },
+    "13": {
+      name: "StemSnapV"
+    },
+    "14": {
+      name: "ForceBold"
+    },
+    "17": {
+      name: "LanguageGroup"
+    },
+    "18": {
+      name: "ExpansionFactor"
+    },
+    "9": {
+      name: "initialRandomSeed"
+    },
+    "20": {
+      name: "SyntheticBase",
+      operand: null
+    },
+    "21": {
+      name: "PostScript",
+      operand: "SID"
+    },
+    "22": {
+      name: "BaseFontName",
+      operand: "SID"
+    },
+    "23": {
+      name: "BaseFontBlend",
+      operand: "delta"
+    }
+  },
+  "13": {
+    name: "UniqueID",
+    operand: null
+  },
+  "14": {
+    name: "XUID",
+    operand: []
+  },
+  "15": {
+    name: "charset",
+    operand: 0
+  },
+  "16": {
+    name: "Encoding",
+    operand: 0
+  },
+  "17": {
+    name: "CharStrings",
+    operand: null
+  },
+  "18": {
+    name: "Private",
+    operand: "number number" 
+  },
+  "19": {
+    name: "Subrs"
+  },
+  "20": {
+    name: "defaultWidthX"
+  },
+  "21": {
+    name: "nominalWidthX"
+  }
+};
+
+var CFFDictPrivateDataMap = {
+  "6": {
+    name: "BluesValues",
+    operand: "delta"
+  },
+  "7": {
+    name: "OtherBlues",
+    operand: "delta"
+  },
+  "8": {
+    name: "FamilyBlues",
+    operand: "delta"
+  },
+  "9": {
+    name: "FamilyOtherBlues",
+    operand: "delta"
+  },
+  "10": {
+    name: "StdHW",
+    operand: null
+  },
+  "11": {
+    name: "StdVW",
+    operand: null
+  },
+  "12": {
+    "9": {
+      name: "BlueScale",
+      operand: 0.039625
+    },
+    "10": {
+      name: "BlueShift",
+      operand: 7
+    },
+    "11": {
+      name: "BlueFuzz",
+      operand: 1
+    },
+    "12": {
+      name: "StemSnapH",
+      operand: "delta"
+    },
+    "13": {
+      name: "StemSnapV",
+      operand: "delta"
+    },
+    "14": {
+      name: "ForceBold",
+      operand: "boolean"
+    },
+    "17": {
+      name: "LanguageGroup",
+      operand: 0
+    },
+    "18": {
+      name: "ExpansionFactor",
+      operand: 0.06
+    },
+    "19": {
+      name: "initialRandomSeed",
+      operand: 0
+    }
+  },
+  "19": {
+    name: "Subrs",
+    operand: null
+  },
+  "20": {
+    name: "defaultWidthX",
+    operand: 0
+  },
+  "21": {
+    name: "nominalWidthX",
+    operand: 0
+  }
+};
+
diff --git a/fonts.js b/fonts.js
new file mode 100644
index 000000000..5390abba4
--- /dev/null
+++ b/fonts.js
@@ -0,0 +1,1484 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+/**
+ * Maximum file size of the font.
+ */
+var kMaxFontFileSize = 40000;
+
+/**
+ * Maximum number of glyphs per font.
+*/
+var kMaxGlyphsCount = 65526;
+
+/**
+ * Maximum time to wait for a font to be loaded by @font-face
+ */
+var kMaxWaitForFontFace = 1000;
+
+/**
+ * Useful for debugging when you want to certains operations depending on how
+ * many fonts are loaded.
+ */
+var fontCount = 0;
+
+/**
+ * Hold a map of decoded fonts and of the standard fourteen Type1 fonts and
+ * their acronyms.
+ * TODO Add the standard fourteen Type1 fonts list by default
+ *      http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65
+ */
+var Fonts = {
+  _active: null,
+  get active() {
+    return this._active || { encoding: [] };
+  },
+
+  set active(aName) {
+    this._active = this[aName];
+  },
+
+  unicodeFromCode: function fonts_unicodeFromCode(aCode) {
+    var unicode = GlyphsUnicode[this.active.encoding[aCode]];
+    return unicode ? unicode : aCode;
+  }
+};
+
+/**
+ * 'Font' is the class the outside world should use, it encapsulate all the font
+ * decoding logics whatever type it is (assuming the font type is supported).
+ *
+ * For example to read a Type1 font and to attach it to the document:
+ *   var type1Font = new Font("MyFontName", binaryData, aFontEncoding, "Type1");
+ *   type1Font.bind();
+ *
+ * As an improvment the last parameter can be replaced by an automatic guess
+ * of the font type based on the first byte of the file.
+ *
+ * FIXME There is now too many parameters, this should be turned into an
+ * object containing all the required informations about the font
+ */
+var Font = function(aName, aFile, aEncoding, aCharset, aBBox, aType) {
+  this.name = aName;
+
+  // If the font has already been decoded simply return
+  if (Fonts[aName]) {
+    this.font = Fonts[aName].data;
+    return;
+  }
+  fontCount++;
+
+  var start = Date.now();
+  switch (aType) {
+    case "Type1":
+      var cff = new CFF(aName, aBBox, aFile);
+      this.mimetype = "font/otf";
+
+      // Wrap the CFF data inside an OTF font file
+      this.font = this.cover(cff);
+      break;
+
+    case "TrueType":
+      return Fonts[aName] = {
+        data: null,
+        encoding: {},
+        charset: null,
+        loading: false
+      };
+
+      // TrueType is disabled for the moment since the sanitizer prevent it
+      // from loading
+      this.mimetype = "font/ttf";
+      var ttf = new TrueType(aFile);
+      this.font = ttf.data;
+      break;
+
+    default:
+      warn("Font " + aType + " is not supported");
+      break;
+  }
+  var end = Date.now();
+
+  Fonts[aName] = {
+    data: this.font,
+    encoding: aEncoding,
+    charset: aCharset ? aCharset.slice() : null,
+    loading: true
+  }
+
+  // Attach the font to the document
+  this.bind();
+};
+
+
+/**
+ * A bunch of the OpenType code is duplicate between this class and the
+ * TrueType code, this is intentional and will merge in a future version
+ * where all the code relative to OpenType will probably have its own
+ * class and will take decision without the Fonts consent.
+ * But at the moment it allows to develop around the TrueType rewriting
+ * on the fly without messing up with the 'regular' Type1 to OTF conversion.
+ */
+Font.prototype = {
+  name: null,
+  font: null,
+  mimetype: null,
+
+  bind: function font_bind() {
+    var data = this.font;
+
+    // Compute the binary data to base 64
+    var str = [];
+    var count = data.length;
+    for (var i = 0; i < count; i++)
+      str.push(data.getChar ? data.getChar()
+                            : String.fromCharCode(data[i]));
+
+    var dataBase64 = window.btoa(str.join(""));
+    var fontName = this.name;
+
+    /** Hack begin */
+
+    // Actually there is not event when a font has finished downloading so
+    // the following tons of code are a dirty hack to 'guess' when a font is
+    // ready
+    var debug = false;
+
+    if (debug) {
+      var name = document.createElement("font");
+      name.setAttribute("style", "position: absolute; left: 20px; top: " +
+                                 (100 * fontCount + 60) + "px");
+      name.innerHTML = fontName;
+      document.body.appendChild(name);
+    }
+
+    var canvas = document.createElement("canvas");
+    var style = "border: 1px solid black; position:absolute; top: " +
+                (debug ? (100 * fontCount) : "-200") + "px; left: 2px; width: 340px; height: 100px";
+    canvas.setAttribute("style", style);
+    canvas.setAttribute("width", 340);
+    canvas.setAttribute("heigth", 100);
+    document.body.appendChild(canvas);
+
+    // Retrieve font charset
+    var charset = Fonts[fontName].charset || [];
+    // if the charset is too small make it repeat a few times
+    var count = 30;
+    while (count-- && charset.length <= 30)
+     charset = charset.concat(charset.slice());
+
+    // Get the font size canvas think it will be for 'spaces'
+    var ctx = canvas.getContext("2d");
+    var testString = "     ";
+
+    // When debugging use the characters provided by the charsets to visually
+    // see what's happening
+    if (debug) {
+      for (var i = 0; i < charset.length; i++) {
+        var unicode = GlyphsUnicode[charset[i]];
+        if (!unicode)
+          error("Unicode for " + charset[i] + " is has not been found in the glyphs list");
+        testString += String.fromCharCode(unicode);
+      }
+    }
+    ctx.font = "bold italic 20px " + fontName + ", Symbol, Arial";
+    var textWidth = ctx.mozMeasureText(testString);
+
+    if (debug)
+      ctx.fillText(testString, 20, 20);
+
+    var start = Date.now();
+    var interval = window.setInterval(function canvasInterval(self) {
+      ctx.font = "bold italic 20px " + fontName + ", Symbol, Arial";
+
+      // For some reasons the font has not loaded, so mark it loaded for the
+      // page to proceed but cry
+      if ((Date.now() - start) >= kMaxWaitForFontFace) {
+        window.clearInterval(interval);
+        Fonts[fontName].loading = false;
+        warn("Is " + fontName + " for charset: " + charset + " loaded?");
+      } else if (textWidth != ctx.mozMeasureText(testString)) {
+        window.clearInterval(interval);
+        Fonts[fontName].loading = false;
+      }
+
+      if (debug)
+        ctx.fillText(testString, 20, 50);
+    }, 20, this);
+
+    /** Hack end */
+
+    // Add the @font-face rule to the document
+    var url = "url(data:" + this.mimetype + ";base64," + dataBase64 + ");";
+    var rule = "@font-face { font-family:'" + fontName + "';src:" + url + "}";
+    var styleSheet = document.styleSheets[0];
+    styleSheet.insertRule(rule, styleSheet.length);
+  },
+
+  _createOpenTypeHeader: function font_createOpenTypeHeader(aFile, aOffsets, aNumTables) {
+    // sfnt version (4 bytes)
+    var version = [0x4F, 0x54, 0x54, 0X4F];
+
+    // numTables (2 bytes)
+    var numTables = aNumTables;
+
+    // searchRange (2 bytes)
+    var tablesMaxPower2 = FontsUtils.getMaxPower2(numTables);
+    var searchRange = tablesMaxPower2 * 16;
+
+    // entrySelector (2 bytes)
+    var entrySelector = Math.log(tablesMaxPower2) / Math.log(2);
+
+    // rangeShift (2 bytes)
+    var rangeShift = numTables * 16 - searchRange;
+
+    var header = [].concat(version,
+                           FontsUtils.integerToBytes(numTables, 2),
+                           FontsUtils.integerToBytes(searchRange, 2),
+                           FontsUtils.integerToBytes(entrySelector, 2),
+                           FontsUtils.integerToBytes(rangeShift, 2));
+    aFile.set(header, aOffsets.currentOffset);
+    aOffsets.currentOffset += header.length;
+    aOffsets.virtualOffset += header.length;
+  },
+
+  _createTableEntry: function font_createTableEntry(aFile, aOffsets, aTag, aData) {
+    // tag
+    var tag = [
+      aTag.charCodeAt(0),
+      aTag.charCodeAt(1),
+      aTag.charCodeAt(2),
+      aTag.charCodeAt(3)
+    ];
+
+    // offset
+    var offset = aOffsets.virtualOffset;
+
+    // Per spec tables must be 4-bytes align so add some 0x00 if needed
+    while (aData.length & 3)
+      aData.push(0x00);
+
+    // length
+    var length = aData.length;
+
+    // checksum
+    var checksum = FontsUtils.bytesToInteger(tag) + offset + length;
+
+    var tableEntry = [].concat(tag,
+                               FontsUtils.integerToBytes(checksum, 4),
+                               FontsUtils.integerToBytes(offset, 4),
+                               FontsUtils.integerToBytes(length, 4));
+    aFile.set(tableEntry, aOffsets.currentOffset);
+    aOffsets.currentOffset += tableEntry.length;
+    aOffsets.virtualOffset += aData.length;
+  },
+
+  _createCMAPTable: function font_createCMAPTable(aGlyphs) {
+    var characters = new Uint16Array(kMaxGlyphsCount);
+    for (var i = 0; i < aGlyphs.length; i++)
+      characters[aGlyphs[i].unicode] = i + 1;
+
+    // Separate the glyphs into continuous range of codes, aka segment.
+    var ranges = [];
+    var range = [];
+    var count = characters.length;
+    for (var i = 0; i < count; i++) {
+      if (characters[i]) {
+        range.push(i);
+      } else if (range.length) {
+        ranges.push(range.slice());
+        range = [];
+      }
+    }
+
+    // The size in bytes of the header is equal to the size of the
+    // different fields * length of a short + (size of the 4 parallels arrays
+    // describing segments * length of a short).
+    var headerSize = (12 * 2 + (ranges.length * 4 * 2));
+
+    var segCount = ranges.length + 1;
+    var segCount2 = segCount * 2;
+    var searchRange = FontsUtils.getMaxPower2(segCount) * 2;
+    var searchEntry = Math.log(segCount) / Math.log(2);
+    var rangeShift = 2 * segCount - searchRange;
+    var cmap = [].concat(
+      [
+        0x00, 0x00, // version
+        0x00, 0x01, // numTables
+        0x00, 0x03, // platformID
+        0x00, 0x01, // encodingID
+        0x00, 0x00, 0x00, 0x0C, // start of the table record
+        0x00, 0x04  // format
+      ],
+      FontsUtils.integerToBytes(headerSize, 2), // length
+      [0x00, 0x00], // language
+      FontsUtils.integerToBytes(segCount2, 2),
+      FontsUtils.integerToBytes(searchRange, 2),
+      FontsUtils.integerToBytes(searchEntry, 2),
+      FontsUtils.integerToBytes(rangeShift, 2)
+    );
+
+    // Fill up the 4 parallel arrays describing the segments.
+    var startCount = [];
+    var endCount = [];
+    var idDeltas = [];
+    var idRangeOffsets = [];
+    var glyphsIdsArray = [];
+    var bias = 0;
+    for (var i = 0; i < segCount - 1; i++) {
+      var range = ranges[i];
+      var start = FontsUtils.integerToBytes(range[0], 2);
+      var end = FontsUtils.integerToBytes(range[range.length - 1], 2);
+
+      var delta = FontsUtils.integerToBytes(((range[0] - 1) - bias) % 65536, 2);
+      bias += range.length;
+
+      // deltas are signed shorts
+      delta[0] ^= 0xFF;
+      delta[1] ^= 0xFF;
+      delta[1] += 1;
+
+      startCount.push(start[0], start[1]);
+      endCount.push(end[0], end[1]);
+      idDeltas.push(delta[0], delta[1]);
+      idRangeOffsets.push(0x00, 0x00);
+
+      for (var j = 0; j < range.length; j++)
+        glyphsIdsArray.push(range[j]);
+    }
+    startCount.push(0xFF, 0xFF);
+    endCount.push(0xFF, 0xFF);
+    idDeltas.push(0x00, 0x01);
+    idRangeOffsets.push(0x00, 0x00);
+
+    return cmap.concat(endCount, [0x00, 0x00], startCount,
+                       idDeltas, idRangeOffsets, glyphsIdsArray);
+  },
+
+  cover: function font_cover(aFont) {
+    var otf = new Uint8Array(kMaxFontFileSize);
+
+    // Required Tables
+    var CFF = aFont.data, // PostScript Font Program
+        OS2 = [],         // OS/2 and Windows Specific metrics
+        cmap = [],        // Character to glyphs mapping
+        head = [],        // Font eader
+        hhea = [],        // Horizontal header
+        hmtx = [],        // Horizontal metrics
+        maxp = [],        // Maximum profile
+        name = [],        // Naming tables
+        post = [];        // PostScript informations
+    var tables = [CFF, OS2, cmap, head, hhea, hmtx, maxp, name, post];
+
+    // The offsets object holds at the same time a representation of where
+    // to write the table entry information about a table and another offset
+    // representing the offset where to draw the actual data of a particular
+    // table
+    var offsets = {
+      currentOffset: 0,
+      virtualOffset: tables.length * (4 * 4)
+    };
+
+    // For files with only one font the offset table is the first thing of the
+    // file
+    this._createOpenTypeHeader(otf, offsets, tables.length);
+
+    // XXX It is probable that in a future we want to get rid of this glue
+    // between the CFF and the OTF format in order to be able to embed TrueType
+    // data.
+    this._createTableEntry(otf, offsets, "CFF ", CFF);
+
+    /** OS/2 */
+    OS2 = [
+      0x00, 0x03, // version
+      0x02, 0x24, // xAvgCharWidth
+      0x01, 0xF4, // usWeightClass
+      0x00, 0x05, // usWidthClass
+      0x00, 0x00, // fstype
+      0x02, 0x8A, // ySubscriptXSize
+      0x02, 0xBB, // ySubscriptYSize
+      0x00, 0x00, // ySubscriptXOffset
+      0x00, 0x8C, // ySubscriptYOffset
+      0x02, 0x8A, // ySuperScriptXSize
+      0x02, 0xBB, // ySuperScriptYSize
+      0x00, 0x00, // ySuperScriptXOffset
+      0x01, 0xDF, // ySuperScriptYOffset
+      0x00, 0x31, // yStrikeOutSize
+      0x01, 0x02, // yStrikeOutPosition
+      0x00, 0x00, // sFamilyClass
+      0x02, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Panose
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 0-31)
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 32-63)
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 64-95)
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 96-127)
+      0x2A, 0x32, 0x31, 0x2A, // achVendID
+      0x00, 0x20, // fsSelection
+      0x00, 0x2D, // usFirstCharIndex
+      0x00, 0x7A, // usLastCharIndex
+      0x00, 0x03, // sTypoAscender
+      0x00, 0x20, // sTypeDescender
+      0x00, 0x38, // sTypoLineGap
+      0x00, 0x5A, // usWinAscent
+      0x02, 0xB4, // usWinDescent
+      0x00, 0xCE, 0x00, 0x00, // ulCodePageRange1 (Bits 0-31)
+      0x00, 0x01, 0x00, 0x00, // ulCodePageRange2 (Bits 32-63)
+      0x00, 0x00, // sxHeight
+      0x00, 0x00, // sCapHeight
+      0x00, 0x01, // usDefaultChar
+      0x00, 0xCD, // usBreakChar
+      0x00, 0x02  // usMaxContext
+    ];
+    this._createTableEntry(otf, offsets, "OS/2", OS2);
+
+    //XXX Getting charstrings here seems wrong since this is another CFF glue
+    var charstrings = aFont.getOrderedCharStrings(aFont.glyphs);
+
+    /** CMAP */
+    cmap = this._createCMAPTable(charstrings);
+    this._createTableEntry(otf, offsets, "cmap", cmap);
+
+    /** HEAD */
+    head = [
+      0x00, 0x01, 0x00, 0x00, // Version number
+      0x00, 0x00, 0x50, 0x00, // fontRevision
+      0x00, 0x00, 0x00, 0x00, // checksumAdjustement
+      0x5F, 0x0F, 0x3C, 0xF5, // magicNumber
+      0x00, 0x00, // Flags
+      0x03, 0xE8, // unitsPerEM (defaulting to 1000)
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // creation date
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // modifification date
+      0x00, 0x00, // xMin
+      0x00, 0x00, // yMin
+      0x00, 0x00, // xMax
+      0x00, 0x00, // yMax
+      0x00, 0x00, // macStyle
+      0x00, 0x00, // lowestRecPPEM
+      0x00, 0x00, // fontDirectionHint
+      0x00, 0x00, // indexToLocFormat
+      0x00, 0x00  // glyphDataFormat
+    ];
+    this._createTableEntry(otf, offsets, "head", head);
+
+    /** HHEA */
+    hhea = [].concat(
+      [
+        0x00, 0x01, 0x00, 0x00, // Version number
+        0x00, 0x00, // Typographic Ascent
+        0x00, 0x00, // Typographic Descent
+        0x00, 0x00, // Line Gap
+        0xFF, 0xFF, // advanceWidthMax
+        0x00, 0x00, // minLeftSidebearing
+        0x00, 0x00, // minRightSidebearing
+        0x00, 0x00, // xMaxExtent
+        0x00, 0x00, // caretSlopeRise
+        0x00, 0x00, // caretSlopeRun
+        0x00, 0x00, // caretOffset
+        0x00, 0x00, // -reserved-
+        0x00, 0x00, // -reserved-
+        0x00, 0x00, // -reserved-
+        0x00, 0x00, // -reserved-
+        0x00, 0x00 // metricDataFormat
+      ],
+      FontsUtils.integerToBytes(charstrings.length, 2) // numberOfHMetrics
+    );
+    this._createTableEntry(otf, offsets, "hhea", hhea);
+
+    /** HMTX */
+    hmtx = [0x01, 0xF4, 0x00, 0x00];
+    for (var i = 0; i < charstrings.length; i++) {
+      var charstring = charstrings[i].charstring;
+      var width = FontsUtils.integerToBytes(charstring[1], 2);
+      var lsb = FontsUtils.integerToBytes(charstring[0], 2);
+      hmtx = hmtx.concat(width, lsb);
+    }
+    this._createTableEntry(otf, offsets, "hmtx", hmtx);
+
+    /** MAXP */
+    maxp = [].concat(
+      [
+        0x00, 0x00, 0x50, 0x00, // Version number
+      ],
+      FontsUtils.integerToBytes(charstrings.length + 1, 2) // Num of glyphs (+1 to pass the sanitizer...)
+    );
+    this._createTableEntry(otf, offsets, "maxp", maxp);
+
+    /** NAME */
+    name = [
+      0x00, 0x00, // format
+      0x00, 0x00, // Number of names Record
+      0x00, 0x00  // Storage
+    ];
+    this._createTableEntry(otf, offsets, "name", name);
+
+    /** POST */
+    // FIXME Get those informations from the FontInfo structure
+    post = [
+      0x00, 0x03, 0x00, 0x00, // Version number
+      0x00, 0x00, 0x01, 0x00, // italicAngle
+      0x00, 0x00, // underlinePosition
+      0x00, 0x00, // underlineThickness
+      0x00, 0x00, 0x00, 0x00, // isFixedPitch
+      0x00, 0x00, 0x00, 0x00, // minMemType42
+      0x00, 0x00, 0x00, 0x00, // maxMemType42
+      0x00, 0x00, 0x00, 0x00, // minMemType1
+      0x00, 0x00, 0x00, 0x00  // maxMemType1
+    ];
+    this._createTableEntry(otf, offsets, "post", post);
+
+    // Once all the table entries header are written, dump the data!
+    var tables = [CFF, OS2, cmap, head, hhea, hmtx, maxp, name, post];
+    for (var i = 0; i < tables.length; i++) {
+      var table = tables[i];
+      otf.set(table, offsets.currentOffset);
+      offsets.currentOffset += table.length;
+    }
+
+    var fontData = [];
+    for (var i = 0; i < offsets.currentOffset; i++)
+      fontData.push(otf[i]);
+    return fontData;
+  }
+};
+
+
+/**
+ * FontsUtils is a static class dedicated to hold codes that are not related
+ * to fonts in particular and needs to be share between them.
+ */
+var FontsUtils = {
+  _bytesArray: new Uint8Array(4),
+  integerToBytes: function fu_integerToBytes(aValue, aBytesCount) {
+    var bytes = this._bytesArray;
+
+    if (aBytesCount == 1) {
+      bytes.set([aValue]);
+      return bytes[0];
+    } else if (aBytesCount == 2) {
+      bytes.set([aValue >> 8, aValue]);
+      return [bytes[0], bytes[1]];
+    } else if (aBytesCount == 4) {
+      bytes.set([aValue >> 24, aValue >> 16, aValue >> 8, aValue]);
+      return [bytes[0], bytes[1], bytes[2], bytes[3]];
+    }
+  },
+
+  bytesToInteger: function fu_bytesToInteger(aBytesArray) {
+    var value = 0;
+    for (var i = 0; i < aBytesArray.length; i++)
+      value = (value << 8) + aBytesArray[i];
+    return value;
+  },
+
+  getMaxPower2: function fu_getMaxPower2(aNumber) {
+    var maxPower = 0;
+    var value = aNumber;
+    while (value >= 2) {
+      value /= 2;
+      maxPower++;
+    }
+
+    value = 2;
+    for (var i = 1; i < maxPower; i++)
+      value *= 2;
+    return value;
+  }
+};
+
+
+/**
+ * The TrueType class verify that the ttf embedded inside the PDF is correct in
+ * the point of view of the OTS sanitizer and rewrite it on the fly otherwise.
+ *
+ * At the moment the rewiting only support rewriting missing 'OS/2' table.
+ * This class is unused at the moment since the 'cmap' table of the test 
+ * document is not missing but use and old version of the 'cmap' table that
+ * is deprecated and  not supported by the sanitizer...
+ *
+ */
+var TrueType = function(aFile) {
+  var header = this._readOpenTypeHeader(aFile);
+  var numTables = header.numTables;
+
+  // Check that required tables are present
+  var requiredTables = [
+    "OS/2",
+    "cmap",
+    "head",
+    "hhea",
+    "hmtx",
+    "maxp",
+    "name",
+    "post"
+  ];
+
+  var tables = [];
+  for (var i = 0; i < numTables; i++) {
+    var table = this._readTableEntry(aFile);
+    var index = requiredTables.indexOf(table.tag);
+    if (index != -1)
+      requiredTables.splice(index, 1);
+
+    tables.push(table);
+  }
+
+  // Tables needs to be written by ascendant alphabetic order
+  tables.sort(function(a, b) {
+    return a.tag > b.tag;
+  });
+
+  // If any tables are still in the array this means some required tables are
+  // missing, which means that we need to rebuild the font in order to pass
+  // the sanitizer.
+  if (requiredTables.length && requiredTables[0] == "OS/2") {
+    OS2 = [
+      0x00, 0x03, // version
+      0x02, 0x24, // xAvgCharWidth
+      0x01, 0xF4, // usWeightClass
+      0x00, 0x05, // usWidthClass
+      0x00, 0x00, // fstype
+      0x02, 0x8A, // ySubscriptXSize
+      0x02, 0xBB, // ySubscriptYSize
+      0x00, 0x00, // ySubscriptXOffset
+      0x00, 0x8C, // ySubscriptYOffset
+      0x02, 0x8A, // ySuperScriptXSize
+      0x02, 0xBB, // ySuperScriptYSize
+      0x00, 0x00, // ySuperScriptXOffset
+      0x01, 0xDF, // ySuperScriptYOffset
+      0x00, 0x31, // yStrikeOutSize
+      0x01, 0x02, // yStrikeOutPosition
+      0x00, 0x00, // sFamilyClass
+      0x02, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Panose
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 0-31)
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 32-63)
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 64-95)
+      0xFF, 0xFF, 0xFF, 0xFF, // ulUnicodeRange1 (Bits 96-127)
+      0x2A, 0x32, 0x31, 0x2A, // achVendID
+      0x00, 0x20, // fsSelection
+      0x00, 0x2D, // usFirstCharIndex
+      0x00, 0x7A, // usLastCharIndex
+      0x00, 0x03, // sTypoAscender
+      0x00, 0x20, // sTypeDescender
+      0x00, 0x38, // sTypoLineGap
+      0x00, 0x5A, // usWinAscent
+      0x02, 0xB4, // usWinDescent
+      0x00, 0xCE, 0x00, 0x00, // ulCodePageRange1 (Bits 0-31)
+      0x00, 0x01, 0x00, 0x00, // ulCodePageRange2 (Bits 32-63)
+      0x00, 0x00, // sxHeight
+      0x00, 0x00, // sCapHeight
+      0x00, 0x01, // usDefaultChar
+      0x00, 0xCD, // usBreakChar
+      0x00, 0x02  // usMaxContext
+    ];
+
+    // Create a new file to hold the new version of our truetype with a new
+    // header and new offsets
+    var stream = aFile.stream || aFile;
+    var ttf = new Uint8Array(stream.length + 16 + OS2.length);
+
+    // The new numbers of tables will be the last one plus the num of missing
+    // tables
+    var numTables = header.numTables + 1;
+
+    // The offsets object holds at the same time a representation of where
+    // to write the table entry information about a table and another offset
+    // representing the offset where to draw the actual data of a particular
+    // table
+    var offsets = {
+      currentOffset: 0,
+      virtualOffset: numTables * (4 * 4)
+    };
+
+    // Write the sfnt header with one more table
+    this._createOpenTypeHeader(ttf, offsets, numTables);
+
+    // Insert the missing table
+    tables.unshift({
+      tag: "OS/2",
+      data: OS2
+    });
+
+    // rewrite the tables but tweak offsets
+    for (var i = 0; i < tables.length; i++) {
+      var table = tables[i];
+      var data = [];
+
+      var tableData = table.data;
+      for (var j = 0; j < tableData.length; j++)
+        data.push(tableData[j]);
+      this._createTableEntry(ttf, offsets, table.tag, data);
+    }
+
+    // Add the table datas
+    for (var i = 0; i < tables.length; i++) {
+      var table = tables[i];
+      var tableData = table.data;
+      ttf.set(tableData, offsets.currentOffset);
+      offsets.currentOffset += tableData.length;
+
+      if (0) {
+        var data = [];
+        for (var j = 0; j < tableData.length; j++)
+          d.push(tableData[j]);
+        log("data for table: " + table.tag + ": " + data);
+      }
+
+      // 4-byte aligned data
+      while (offsets.currentOffset & 3)
+        offsets.currentOffset++;
+    }
+
+    var fontData = [];
+    for (var i = 0; i < ttf.length; i++)
+      fontData.push(ttf[i]);
+
+    this.data = ttf;
+    return;
+  } else if (requiredTables.lenght) {
+    error("Table " + requiredTables[0] + " is missing from the TruType font");
+  } else {
+    this.data = aFile;
+  }
+};
+
+TrueType.prototype = {
+  _createOpenTypeHeader: function tt_createOpenTypeHeader(aFile, aOffsets, aNumTables) {
+    // sfnt version (4 bytes)
+    // XXX if we want to merge this function and the one from the Font class
+    // XXX this need to be adapted
+    var version = [0x00, 0x01, 0x00, 0X00];
+
+    // numTables (2 bytes)
+    var numTables = aNumTables;
+
+    // searchRange (2 bytes)
+    var tablesMaxPower2 = FontsUtils.getMaxPower2(numTables);
+    var searchRange = tablesMaxPower2 * 16;
+
+    // entrySelector (2 bytes)
+    var entrySelector = Math.log(tablesMaxPower2) / Math.log(2);
+
+    // rangeShift (2 bytes)
+    var rangeShift = numTables * 16 - searchRange;
+
+    var header = [].concat(version,
+                           FontsUtils.integerToBytes(numTables, 2),
+                           FontsUtils.integerToBytes(searchRange, 2),
+                           FontsUtils.integerToBytes(entrySelector, 2),
+                           FontsUtils.integerToBytes(rangeShift, 2));
+    aFile.set(header, aOffsets.currentOffset);
+    aOffsets.currentOffset += header.length;
+    aOffsets.virtualOffset += header.length;
+  },
+
+  _createTableEntry: function font_createTableEntry(aFile, aOffsets, aTag, aData) {
+    // tag
+    var tag = [
+      aTag.charCodeAt(0),
+      aTag.charCodeAt(1),
+      aTag.charCodeAt(2),
+      aTag.charCodeAt(3)
+    ];
+
+    // Per spec tables must be 4-bytes align so add some 0x00 if needed
+    while (aData.length & 3)
+      aData.push(0x00);
+
+    while (aOffsets.virtualOffset & 3)
+      aOffsets.virtualOffset++;
+
+    // offset
+    var offset = aOffsets.virtualOffset;
+
+    // length
+    var length = aData.length;
+
+    // checksum
+    var checksum = FontsUtils.bytesToInteger(tag) + offset + length;
+
+    var tableEntry = [].concat(tag,
+                               FontsUtils.integerToBytes(checksum, 4),
+                               FontsUtils.integerToBytes(offset, 4),
+                               FontsUtils.integerToBytes(length, 4));
+    aFile.set(tableEntry, aOffsets.currentOffset);
+    aOffsets.currentOffset += tableEntry.length;
+    aOffsets.virtualOffset += aData.length;
+  },
+
+  _readOpenTypeHeader: function tt_readOpenTypeHeader(aFile) {
+    return {
+      version: aFile.getBytes(4),
+      numTables: FontsUtils.bytesToInteger(aFile.getBytes(2)),
+      searchRange: FontsUtils.bytesToInteger(aFile.getBytes(2)),
+      entrySelector: FontsUtils.bytesToInteger(aFile.getBytes(2)),
+      rangeShift: FontsUtils.bytesToInteger(aFile.getBytes(2))
+    }
+  },
+
+  _readTableEntry: function tt_readTableEntry(aFile) {
+    // tag
+    var tag = aFile.getBytes(4);
+    tag = String.fromCharCode(tag[0]) +
+          String.fromCharCode(tag[1]) +
+          String.fromCharCode(tag[2]) +
+          String.fromCharCode(tag[3]);
+
+    var checksum = FontsUtils.bytesToInteger(aFile.getBytes(4));
+    var offset = FontsUtils.bytesToInteger(aFile.getBytes(4));
+    var length = FontsUtils.bytesToInteger(aFile.getBytes(4));
+
+    // Read the table associated data
+    var currentPosition = aFile.pos;
+    aFile.pos = aFile.start + offset;
+    var data = aFile.getBytes(length);
+    aFile.pos = currentPosition;
+
+    return {
+      tag: tag,
+      checksum: checksum,
+      length: offset,
+      offset: length,
+      data: data
+    }
+  }
+};
+
+
+/**
+ * This dictionary holds decoded fonts data.
+ */
+var Type1Parser = function() {
+  // Turn on this flag for additional debugging logs
+  var debug = false;
+
+  var dump = function(aData) {
+    if (debug)
+      log(aData);
+  };
+
+  /*
+   * Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence
+   * of Plaintext Bytes. The function took a key as a parameter which can be
+   * for decrypting the eexec block of for decoding charStrings.
+   */
+  var kEexecEncryptionKey = 55665;
+  var kCharStringsEncryptionKey = 4330;
+
+  function decrypt(aStream, aKey, aDiscardNumber, aByteArray) {
+    var start = Date.now();
+    var r = aKey, c1 = 52845, c2 = 22719;
+    var decryptedString = [];
+
+    var value = "";
+    var count = aStream.length;
+    for (var i = 0; i < count; i++) {
+      value = aStream[i];
+      if (aByteArray)
+        decryptedString[i] = value ^ (r >> 8);
+      else
+        decryptedString[i] = String.fromCharCode(value ^ (r >> 8));
+      r = ((value + r) * c1 + c2) & ((1 << 16) - 1);
+    }
+    var end = Date.now();
+    dump("Time to decrypt string of length " + count + " is " + (end - start));
+    return decryptedString.slice(aDiscardNumber);
+  };
+
+  /*
+   * CharStrings are encoded following the the CharString Encoding sequence
+   * describe in Chapter 6 of the "Adobe Type1 Font Format" specification.
+   * The value in a byte indicates a command, a number, or subsequent bytes
+   * that are to be interpreted in a special way.
+   *
+   * CharString Number Encoding:
+   *  A CharString byte containing the values from 32 through 255 inclusive
+   *  indicate an integer. These values are decoded in four ranges.
+   *
+   * 1. A CharString byte containing a value, v, between 32 and 246 inclusive,
+   * indicate the integer v - 139. Thus, the integer values from -107 through
+   * 107 inclusive may be encoded in single byte.
+   *
+   * 2. A CharString byte containing a value, v, between 247 and 250 inclusive,
+   * indicates an integer involving the next byte, w, according to the formula:
+   * [(v - 247) x 256] + w + 108
+   *
+   * 3. A CharString byte containing a value, v, between 251 and 254 inclusive,
+   * indicates an integer involving the next byte, w, according to the formula:
+   * -[(v - 251) * 256] - w - 108
+   *
+   * 4. A CharString containing the value 255 indicates that the next 4 bytes
+   * are a two complement signed integer. The first of these bytes contains the
+   * highest order bits, the second byte contains the next higher order bits
+   * and the fourth byte contain the lowest order bits.
+   *
+   *
+   * CharString Command Encoding:
+   *  CharStrings commands are encoded in 1 or 2 bytes.
+   *
+   *  Single byte commands are encoded in 1 byte that contains a value between
+   *  0 and 31 inclusive.
+   *  If a command byte contains the value 12, then the value in the next byte
+   *  indicates a command. This "escape" mechanism allows many extra commands
+   * to be encoded and this encoding technique helps to minimize the length of
+   * the charStrings.
+   */
+  var charStringDictionary = {
+    "1": "hstem",
+    "3": "vstem",
+    "4": "vmoveto",
+    "5": "rlineto",
+    "6": "hlineto",
+    "7": "vlineto",
+    "8": "rrcurveto",
+
+    // closepath is a Type1 command that do not take argument and is useless
+    // in Type2 and it can simply be ignored.
+    "9": null, // closepath
+
+    "10": "callsubr",
+
+    // return is normally used inside sub-routines to tells to the execution
+    // flow that it can be back to normal.
+    // During the translation process Type1 charstrings will be flattened and
+    // sub-routines will be embedded directly into the charstring directly, so
+    // this can be ignored safely.
+    "11": "return",
+
+    "12": {
+      // dotsection is a Type1 command to specify some hinting feature for dots
+      // that do not take a parameter and it can safely be ignored for Type2.
+      "0": null, // dotsection
+
+      // [vh]stem3 are Type1 only and Type2 supports [vh]stem with multiple
+      // parameters, so instead of returning [vh]stem3 take a shortcut and
+      // return [vhstem] instead.
+      "1": "vstem",
+      "2": "hstem",
+
+      // Type1 only command with command not (yet) built-in ,throw an error
+      "6": -1, // seac
+      "7": -1, //sbw
+
+      "12": "div",
+
+      // callothersubr is a mechanism to make calls on the postscript
+      // interpreter.
+      // TODO When decodeCharstring encounter such a command it should
+      //      directly do:
+      //        - pop the previous charstring[] command into 'index'
+      //        - pop the previous charstring[] command and ignore it, it is
+      //          normally the number of element to push on the stack before
+      //          the command but since everything will be pushed on the stack
+      //          by the PS interpreter when it will read them that is safe to
+      //          ignore this command
+      //        - push the content of the OtherSubrs[index] inside charstring[]
+      "16": "callothersubr",
+
+      "17": "pop",
+
+      // setcurrentpoint sets the current point to x, y without performing a
+      // moveto (this is a one shot positionning command). This is used only
+      // with the return of an OtherSubrs call.
+      // TODO Implement the OtherSubrs charstring embedding and replace this
+      //      call by a no-op, like 2 'pop' commands for example.
+      "33": null, //setcurrentpoint
+    },
+    "13": "hsbw",
+    "14": "endchar",
+    "21": "rmoveto",
+    "22": "hmoveto",
+    "30": "vhcurveto",
+    "31": "hvcurveto"
+  };
+
+  function decodeCharString(aArray) {
+    var charString = [];
+
+    var value = "";
+    var count = aArray.length;
+    for (var i = 0; i < count; i++) {
+      value = parseInt(aArray[i]);
+
+      if (value < 32) {
+        var command = null;
+        if (value == 12) {
+          var escape = aArray[++i];
+          command = charStringDictionary["12"][escape];
+        } else {
+          command = charStringDictionary[value];
+        }
+
+        // Some charstring commands are meaningless in Type2 and will return
+        // a null, let's just ignored them
+        if (!command && i < count) {
+          continue;
+        } else if (!command) {
+          break;
+        } else if (command == -1) {
+          log("decodeCharstring: " + charString);
+          error("Support for Type1 command " + value + " (" + escape + ") is not implemented");
+        }
+
+        value = command;
+      } else if (value <= 246) {
+        value = parseInt(value) - 139;
+      } else if (value <= 250) {
+        value = ((value - 247) * 256) + parseInt(aArray[++i]) + 108;
+      } else if (value <= 254) {
+        value = -((value - 251) * 256) - parseInt(aArray[++i]) - 108;
+      } else {
+        var byte = aArray[++i];
+        var high = (byte >> 1);
+        value = (byte - high) << 24 | aArray[++i] << 16 |
+                aArray[++i] << 8 | aArray[++i];
+      }
+
+      charString.push(value);
+    }
+
+    return charString;
+  };
+
+  /**
+   * Returns an object containing a Subrs array and a CharStrings array
+   * extracted from and eexec encrypted block of data
+   */
+  this.extractFontInfo = function(aStream) {
+    var eexecString = decrypt(aStream, kEexecEncryptionKey, 4, true);
+    var subrs = [],  glyphs = [];
+    var inSubrs = inGlyphs = false;
+    var glyph = "";
+
+    var token = "";
+    var index = 0;
+    var length = 0;
+
+    var count = eexecString.length;
+    var c = "";
+    for (var i = 0; i < count; i++) {
+      var c = eexecString[i];
+
+      if (inSubrs && c == 0x52) {
+        length = parseInt(length);
+        var data = eexecString.slice(i + 3, i + 3 + length);
+        var encodedSubr = decrypt(data, kCharStringsEncryptionKey, 4, true);
+        var subr = decodeCharString(encodedSubr);
+
+        subrs.push(subr);
+        i += 3 + length;
+      } else if (inGlyphs && c == 0x52) {
+        length = parseInt(length);
+        var data = eexecString.slice(i + 3, i + 3 + length);
+        var encodedCharstring = decrypt(data, kCharStringsEncryptionKey, 4, true);
+        var subr = decodeCharString(encodedCharstring);
+
+        glyphs.push({
+            glyph: glyph,
+            data: subr
+        });
+        i += 3 + length;
+      } else if (inGlyphs && c == 0x2F) {
+        token = "";
+        glyph = "";
+
+        while ((c = eexecString[++i]) != 0x20)
+          glyph += String.fromCharCode(c);
+      } else if (!inSubrs && !inGlyphs && c == 0x2F && eexecString[i+1] == 0x53) {
+        while ((c = eexecString[++i]) != 0x20) {};
+        inSubrs = true;
+      } else if (c == 0x20) {
+        index = length;
+        length = token;
+        token = "";
+      } else if (c == 0x2F && eexecString[i+1] == 0x43 && eexecString[i+2] == 0x68) {
+        while ((c = eexecString[++i]) != 0x20) {};
+        inSubrs = false;
+        inGlyphs = true;
+      } else {
+        token += String.fromCharCode(c);
+      }
+    }
+    return {
+      subrs: subrs,
+      charstrings: glyphs
+    }
+  }
+};
+
+var CFF = function(aFontName, aFontBBox, aFontFile) {
+  // Get the data block containing glyphs and subrs informations
+  var length1 = aFontFile.dict.get("Length1");
+  var length2 = aFontFile.dict.get("Length2");
+  aFontFile.skip(length1);
+  var eexecBlock = aFontFile.getBytes(length2);
+
+  // Extract informations from it
+  var start = Date.now();
+  var parser = new Type1Parser();
+  var fontInfo = parser.extractFontInfo(eexecBlock);
+  fontInfo.name = aFontName;
+  fontInfo.bbox = aFontBBox;
+
+  // XXX This hold the glyph data as if, this should be improved
+  this.glyphs = fontInfo.charstrings;
+
+  this.data = this.convertToCFF(fontInfo);
+  var end = Date.now();
+};
+
+CFF.prototype = {
+  createCFFIndexHeader: function(aObjects, aIsByte) {
+    var data = [];
+
+    // First 2 bytes contains the number of objects contained into this index
+    var count = aObjects.length;
+    if (count ==0)
+      return [0x00, 0x00, 0x00];
+
+    var bytes = FontsUtils.integerToBytes(count, 2);
+    for (var i = 0; i < bytes.length; i++)
+      data.push(bytes[i]);
+
+    // Next byte contains the offset size use to reference object in the file
+    // Actually we're using 0x04 to be sure to be able to store everything
+    // without thinking of it while coding.
+    data.push(0x04);
+
+    // Add another offset after this one because we need a new offset
+    var relativeOffset = 1;
+    for (var i = 0; i < count + 1; i++) {
+      var bytes = FontsUtils.integerToBytes(relativeOffset, 4);
+      for (var j = 0; j < bytes.length; j++)
+        data.push(bytes[j]);
+
+      if (aObjects[i])
+        relativeOffset += aObjects[i].length;
+    }
+
+    for (var i =0; i < count; i++) {
+      for (var j = 0; j < aObjects[i].length; j++)
+        data.push(aIsByte ? aObjects[i][j] : aObjects[i].charCodeAt(j));
+    }
+    return data;
+  },
+
+  encodeNumber: function(aValue) {
+    var x = 0;
+    if (aValue >= -32768 && aValue <= 32767) {
+      return [ 28, aValue >> 8, aValue ];
+    } else if (aValue >= (-2147483647-1) && aValue <= 2147483647) {
+      return [
+        0xFF, aValue >> 24, Value >> 16, aValue >> 8, aValue ];
+    } else {
+      error("Value: " + aValue + " is not allowed");
+    }
+  },
+
+  getOrderedCharStrings: function(aGlyphs) {
+    var charstrings = [];
+
+    for (var i = 0; i < aGlyphs.length; i++) {
+      var glyph = aGlyphs[i].glyph;
+      var unicode = GlyphsUnicode[glyph];
+      if (!unicode) {
+        if (glyph != ".notdef")
+          warn(glyph + " does not have an entry in the glyphs unicode dictionary");
+      } else {
+        charstrings.push({
+          glyph: glyph,
+          unicode: unicode,
+          charstring: aGlyphs[i].data.slice()
+        });
+      }
+    };
+
+    charstrings.sort(function(a, b) {
+      return a.unicode > b.unicode;
+    });
+    return charstrings;
+  },
+
+  /*
+   * Flatten the commands by interpreting the postscript code and replacing
+   * every 'callsubr', 'callothersubr' by the real commands.
+   *
+   * TODO This function also do a string to command number transformation
+   * that can probably be avoided if the Type1 decodeCharstring code is smarter
+   */
+  commandsMap: {
+    "hstem": 1,
+    "vstem": 3,
+    "vmoveto": 4,
+    "rlineto": 5,
+    "hlineto": 6,
+    "vlineto": 7,
+    "rrcurveto": 8,
+    "endchar": 14,
+    "rmoveto": 21,
+    "hmoveto": 22,
+    "vhcurveto": 30,
+    "hvcurveto": 31,
+  },
+
+  flattenCharstring: function(aGlyph, aCharstring, aSubrs) {
+    var original = aCharstring.slice();
+    var i = 0;
+    while (true) {
+      var obj = aCharstring[i];
+      if (obj == null)
+        return [];
+
+      if (obj.charAt) {
+        switch (obj) {
+          case "callsubr":
+            var subr = aSubrs[aCharstring[i - 1]].slice();
+            if (subr.length > 1) {
+              subr = this.flattenCharstring(aGlyph, subr, aSubrs);
+              subr.pop();
+              aCharstring.splice(i - 1, 2, subr);
+            } else {
+              aCharstring.splice(i - 1, 2);
+            }
+            i -= 1;
+            break;
+
+          case "callothersubr":
+            var index = aCharstring[i - 1];
+            var count = aCharstring[i - 2];
+            var data = aCharstring[i - 3];
+
+            // XXX The callothersubr needs to support at least the 3 defaults
+            // otherSubrs of the spec
+            if (index != 3)
+              error("callothersubr for index: " + index + " (" + aCharstring + ")");
+
+            if (!data) {
+              aCharstring.splice(i - 2, 4, "pop", 3);
+              i -= 3;
+            } else {
+              // 5 to remove the arguments, the callothersubr call and the pop command
+              aCharstring.splice(i - 3, 5, 3);
+              i -= 3;
+            }
+            break;
+
+          case "div":
+            var num2 = aCharstring[i - 1];
+            var num1 = aCharstring[i - 2];
+            aCharstring.splice(i - 2, 3, num2 / num1);
+            i -= 2;
+            break;
+
+          case "pop":
+            if (i)
+              aCharstring.splice(i - 2, 2);
+            else
+              aCharstring.splice(i - 1, 1);
+            i -= 1;
+            break;
+
+
+          case "hsbw":
+            var charWidthVector = aCharstring[i - 1];
+            var leftSidebearing = aCharstring[i - 2];
+
+            if (leftSidebearing)
+              aCharstring.splice(i - 2, 3, charWidthVector, leftSidebearing, "hmoveto");
+            else
+              aCharstring.splice(i - 2, 3, charWidthVector);
+            break;
+
+          case "endchar":
+          case "return":
+            // CharString is ready to be re-encode to commands number at this point
+            for (var j = 0; j < aCharstring.length; j++) {
+              var command = aCharstring[j];
+              if (parseFloat(command) == command) {
+                aCharstring.splice(j, 1, 28, command >> 8, command);
+                j+= 2;
+              } else if (command.charAt) {
+                var command = this.commandsMap[command];
+                if (IsArray(command)) {
+                  aCharstring.splice(j - 1, 1, command[0], command[1]);
+                  j += 1;
+                } else {
+                  aCharstring[j] = command;
+                }
+              } else {
+                aCharstring.splice(j, 1);
+
+                // command has already been translated, just add them to the
+                // charstring directly
+                for (var k = 0; k < command.length; k++)
+                  aCharstring.splice(j + k, 0, command[k]);
+                j+= command.length - 1;
+              }
+            }
+            return aCharstring;
+
+          default:
+            break;
+        }
+      }
+      i++;
+    }
+    error("failing with i = " + i + " in charstring:" + aCharstring + "(" + aCharstring.length + ")");
+  },
+
+  convertToCFF: function(aFontInfo) {
+    var debug = false;
+    function dump(aMsg) {
+      if (debug)
+        log(aMsg);
+    };
+
+    var charstrings = this.getOrderedCharStrings(aFontInfo.charstrings);
+
+    // Starts the conversion of the Type1 charstrings to Type2
+    var start = Date.now();
+    var charstringsCount = 0;
+    var charstringsDataLength = 0;
+    var glyphs = [];
+    for (var i = 0; i < charstrings.length; i++) {
+      var charstring = charstrings[i].charstring.slice();
+      var glyph = charstrings[i].glyph;
+
+      var flattened = this.flattenCharstring(glyph, charstring, aFontInfo.subrs);
+      glyphs.push(flattened);
+      charstringsCount++;
+      charstringsDataLength += flattened.length;
+    }
+
+    var end = Date.now();
+    dump("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")");
+    dump("Time to flatten the strings is : " + (end -start));
+
+    // Create a CFF font data
+    var cff = new Uint8Array(kMaxFontFileSize);
+    var currentOffset = 0;
+
+    // Font header (major version, minor version, header size, offset size)
+    var header = [0x01, 0x00, 0x04, 0x04];
+    currentOffset += header.length;
+    cff.set(header);
+
+    // Names Index
+    var nameIndex = this.createCFFIndexHeader([aFontInfo.name]);
+    cff.set(nameIndex, currentOffset);
+    currentOffset += nameIndex.length;
+
+    // Calculate strings before writing the TopDICT index in order
+    // to calculate correct relative offsets for storing 'charset'
+    // and 'charstrings' data
+    var version = "";
+    var notice = "";
+    var fullName = "";
+    var familyName = "";
+    var weight = "";
+    var strings = [version, notice, fullName,
+                   familyName, weight];
+    var stringsIndex = this.createCFFIndexHeader(strings);
+    var stringsDataLength = stringsIndex.length;
+
+    // Create the global subroutines index
+    var globalSubrsIndex = this.createCFFIndexHeader([]);
+
+    // Fill the charset header (first byte is the encoding)
+    var charset = [0x00];
+    for (var i = 0; i < glyphs.length; i++) {
+      var index = CFFStrings.indexOf(charstrings[i].glyph);
+      if (index == -1)
+        index = CFFStrings.length + strings.indexOf(glyph);
+      var bytes = FontsUtils.integerToBytes(index, 2);
+      charset.push(bytes[0]);
+      charset.push(bytes[1]);
+    }
+
+    var charstringsIndex = this.createCFFIndexHeader([[0x40, 0x0E]].concat(glyphs), true);
+    charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why?
+
+    //Top Dict Index
+    var topDictIndex = [
+      0x00, 0x01, 0x01, 0x01, 0x30,
+      248, 27, 0, // version
+      248, 28, 1, // Notice
+      248, 29, 2, // FullName
+      248, 30, 3, // FamilyName
+      248, 31, 4  // Weight
+    ];
+
+    var fontBBox = aFontInfo.bbox;
+    for (var i = 0; i < fontBBox.length; i++)
+      topDictIndex = topDictIndex.concat(this.encodeNumber(fontBBox[i]));
+    topDictIndex.push(5) // FontBBox;
+
+    var charsetOffset = currentOffset +
+                        (topDictIndex.length + (4 + 4 + 4 + 7)) +
+                        stringsIndex.length +
+                        globalSubrsIndex.length;
+    topDictIndex = topDictIndex.concat(this.encodeNumber(charsetOffset));
+    topDictIndex.push(15); // charset
+
+    topDictIndex = topDictIndex.concat([28, 0, 0, 16]) // Encoding
+
+    var charstringsOffset = charsetOffset + (charstringsCount * 2) + 1;
+    topDictIndex = topDictIndex.concat(this.encodeNumber(charstringsOffset));
+    topDictIndex.push(17); // charstrings
+
+    topDictIndex = topDictIndex.concat([28, 0, 55])
+    var privateOffset = charstringsOffset + charstringsIndex.length;
+    topDictIndex = topDictIndex.concat(this.encodeNumber(privateOffset));
+    topDictIndex.push(18); // Private
+    topDictIndex = topDictIndex.join(" ").split(" ");
+
+    var indexes = [
+      topDictIndex, stringsIndex,
+      globalSubrsIndex, charset,
+      charstringsIndex
+    ];
+
+    for (var i = 0; i < indexes.length; i++) {
+      var index = indexes[i];
+      cff.set(index, currentOffset);
+      currentOffset += index.length;
+    }
+
+    // Private Data
+    var defaultWidth = this.encodeNumber(0);
+    var privateData = [].concat(
+      defaultWidth, [20],
+      [139, 21], // nominalWidth
+      [
+      119, 159, 248, 97, 159, 247, 87, 159, 6,
+      30, 10, 3, 150, 37, 255, 12, 9,
+      139, 12,
+      10, 172, 10,
+      172, 150, 143, 146, 150, 146, 12, 12,
+      247, 32, 11,
+      247, 10, 161, 147, 154, 150, 143, 12, 13,
+      139, 12, 14,
+      28, 0, 55, 19
+    ]);
+    privateData = privateData.join(" ").split(" ");
+    cff.set(privateData, currentOffset);
+    currentOffset += privateData.length;
+
+    // Dump shit at the end of the file
+    var shit = [
+      0x00, 0x01, 0x01, 0x01,
+      0x13, 0x5D, 0x65, 0x64,
+      0x5E, 0x5B, 0xAF, 0x66,
+      0xBA, 0xBB, 0xB1, 0xB0,
+      0xB9, 0xBA, 0x65, 0xB2,
+      0x5C, 0x1F, 0x0B
+    ];
+    cff.set(shit, currentOffset);
+    currentOffset += shit.length;
+
+    var fontData = [];
+    for (var i = 0; i < currentOffset; i++)
+      fontData.push(cff[i]);
+
+    return fontData;
+  }
+};
+
diff --git a/fonts_utils.js b/fonts_utils.js
new file mode 100644
index 000000000..086648fe2
--- /dev/null
+++ b/fonts_utils.js
@@ -0,0 +1,391 @@
+/**
+ * The Type2 reader code below is only used for debugging purpose since Type2
+ * is only a CharString format and is never used directly as a Font file.
+ *
+ * So the code here is useful for dumping the data content of a .cff file in
+ * order to investigate the similarity between a Type1 CharString and a Type2
+ * CharString or to understand the structure of the CFF format.
+ */
+
+
+/**
+ * Build a charset by assigning the glyph name and the human readable form
+ * of the glyph data.
+ */
+function readCharset(aStream, aCharstrings) {
+  var charset = {};
+
+  var format = aStream.getByte();
+  if (format == 0) {
+    charset[".notdef"] = readCharstringEncoding(aCharstrings[0]);
+
+    var count = aCharstrings.length - 1;
+    for (var i = 1; i < count + 1; i++) {
+      var sid = aStream.getByte() << 8 | aStream.getByte();
+      charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]);
+      //log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]);
+    }
+  } else if (format == 1) {
+    error("Charset Range are not supported");
+  } else {
+    error("Invalid charset format");
+  }
+
+  return charset;
+};
+
+/**
+ * Take a Type2 binary charstring as input and transform it to a human
+ * readable representation as specified by the 'The Type 2 Charstring Format',
+ * chapter 3.1.
+ */
+function readCharstringEncoding(aString) {
+  var charstringTokens = [];
+
+  var count = aString.length;
+  for (var i = 0; i < count; ) {
+    var value = aString[i++];
+    var token = null;
+
+    if (value < 0) {
+      continue;
+    } else if (value <= 11) {
+      token = CFFEncodingMap[value];
+    } else if (value == 12) {
+      token = CFFEncodingMap[value][aString[i++]];
+    } else if (value <= 18) {
+      token = CFFEncodingMap[value];
+    } else if (value <= 20) {
+      var mask = aString[i++];
+      token = CFFEncodingMap[value];
+    } else if (value <= 27) {
+      token = CFFEncodingMap[value];
+    } else if (value == 28) {
+      token = aString[i++] << 8 | aString[i++];
+    } else if (value <= 31) {
+      token = CFFEncodingMap[value];
+    } else if (value < 247) {
+      token = parseInt(value) - 139;
+    } else if (value < 251) {
+      token = ((value - 247) * 256) + aString[i++] + 108;
+    } else if (value < 255) {
+      token = -((value - 251) * 256) - aString[i++] - 108;
+    } else {// value == 255
+      token = aString[i++] << 24 | aString[i++] << 16 |
+              aString[i++] << 8 | aString[i];
+    }
+
+    charstringTokens.push(token);
+  }
+
+  return charstringTokens;
+};
+
+
+/**
+ * Take a binary DICT Data as input and transform it into a human readable
+ * form as specified by 'The Compact Font Format Specification', chapter 5.
+ */
+function readFontDictData(aString, aMap) {
+  var fontDictDataTokens = [];
+
+  var count = aString.length;
+  for (var i = 0; i < count; i) {
+    var value = aString[i++];
+    var token = null;
+
+    if (value == 12) {
+      token = aMap[value][aString[i++]];
+    } else if (value == 28) {
+      token = aString[i++] << 8 | aString[i++];
+    } else if (value == 29) {
+      token = aString[i++] << 24 |
+              aString[i++] << 16 |
+              aString[i++] << 8  |
+              aString[i++];
+    } else if (value == 30) {
+      token = "";
+      var parsed = false;
+      while (!parsed) {
+        var byte = aString[i++];
+
+        var nibbles = [parseInt(byte / 16), parseInt(byte % 16)];
+        for (var j = 0; j < nibbles.length; j++) {
+          var nibble = nibbles[j];
+          switch (nibble) {
+            case 0xA:
+              token += ".";
+              break;
+            case 0xB:
+              token += "E";
+              break;
+            case 0xC:
+              token += "E-";
+              break;
+            case 0xD:
+              break;
+            case 0xE:
+              token += "-";
+              break;
+            case 0xF:
+              parsed = true;
+              break;
+            default:
+              token += nibble;
+              break;
+          }
+        }
+      };
+      token = parseFloat(token);
+    } else if (value <= 31) {
+      token = aMap[value];
+    } else if (value <= 246) {
+      token = parseInt(value) - 139;
+    } else if (value <= 250) {
+      token = ((value - 247) * 256) + aString[i++] + 108;
+    } else if (value <= 254) {
+      token = -((value - 251) * 256) - aString[i++] - 108;
+    } else if (value == 255) {
+      error("255 is not a valid DICT command");
+    }
+
+    fontDictDataTokens.push(token);
+  }
+
+  return fontDictDataTokens;
+};
+
+
+/**
+ * Take a stream as input and return an array of objects.
+ * In CFF an INDEX is a structure with the following format:
+ *  {
+ *    count: 2 bytes (Number of objects stored in INDEX),
+ *    offsize: 1 byte (Offset array element size),
+ *    offset: [count + 1] bytes (Offsets array),
+ *    data: - (Objects data)
+ *  }
+ *
+ *  More explanation are given in the 'CFF Font Format Specification',
+ *  chapter 5.
+ */
+function readFontIndexData(aStream, aIsByte) {
+  var count = aStream.getByte() << 8 | aStream.getByte();
+  var offsize = aStream.getByte();
+
+  function getNextOffset() {
+    switch (offsize) {
+      case 0:
+        return 0;
+      case 1:
+        return aStream.getByte();
+      case 2:
+        return aStream.getByte() << 8 | aStream.getByte();
+      case 3:
+        return aStream.getByte() << 16 | aStream.getByte() << 8 |
+               aStream.getByte();
+      case 4:
+      return aStream.getByte() << 24 | aStream.getByte() << 16 |
+             aStream.getByte() << 8 | aStream.getByte();
+    }
+  };
+
+  var offsets = [];
+  for (var i = 0; i < count + 1; i++)
+    offsets.push(getNextOffset());
+
+  log("Found " + count + " objects at offsets :" + offsets + " (offsize: " + offsize + ")");
+
+  // Now extract the objects
+  var relativeOffset = aStream.pos;
+  var objects = [];
+  for (var i = 0; i < count; i++) {
+    var offset = offsets[i];
+    aStream.pos = relativeOffset + offset - 1;
+
+    var data = [];
+    var length = offsets[i + 1] - 1;
+    for (var j = offset - 1; j < length; j++)
+      data.push(aIsByte ? aStream.getByte() : aStream.getChar());
+    objects.push(data);
+  }
+
+  return objects;
+};
+
+var Type2Parser = function(aFilePath) {
+  var font = new Dict();
+
+  var xhr = new XMLHttpRequest();
+  xhr.open("GET", aFilePath, false);
+  xhr.mozResponseType = xhr.responseType = "arraybuffer";
+  xhr.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200;
+  xhr.send(null);
+  this.data = new Stream(xhr.mozResponseArrayBuffer || xhr.mozResponse ||
+                         xhr.responseArrayBuffer || xhr.response);
+
+  // Turn on this flag for additional debugging logs
+  var debug = false;
+
+  function dump(aStr) {
+    if (debug)
+      log(aStr);
+  };
+
+  function parseAsToken(aString, aMap) {
+    var decoded = readFontDictData(aString, aMap);
+
+    var stack = [];
+    var count = decoded.length;
+    for (var i = 0; i < count; i++) {
+      var token = decoded[i];
+      if (IsNum(token)) {
+        stack.push(token);
+      } else {
+        switch (token.operand) {
+          case "SID":
+            font.set(token.name, CFFStrings[stack.pop()]);
+            break;
+          case "number number":
+            font.set(token.name, {
+              offset: stack.pop(),
+              size: stack.pop()
+            });
+            break;
+          case "boolean":
+            font.set(token.name, stack.pop());
+            break;
+          case "delta":
+            font.set(token.name, stack.pop());
+            break;
+          default:
+            if (token.operand && token.operand.length) {
+              var array = [];
+              for (var j = 0; j < token.operand.length; j++)
+                array.push(stack.pop());
+              font.set(token.name, array);
+            } else {
+              font.set(token.name, stack.pop());
+            }
+            break;
+        }
+      }
+    }
+  };
+
+  this.parse = function(aStream) {
+    font.set("major", aStream.getByte());
+    font.set("minor", aStream.getByte());
+    font.set("hdrSize", aStream.getByte());
+    font.set("offsize", aStream.getByte());
+
+    // Move the cursor after the header
+    aStream.skip(font.get("hdrSize") - aStream.pos);
+
+    // Read the NAME Index
+    dump("Reading Index: Names");
+    font.set("Names", readFontIndexData(aStream));
+    log("Names: " + font.get("Names"));
+
+    // Read the Top Dict Index
+    dump("Reading Index: TopDict");
+    var topDict = readFontIndexData(aStream, true);
+    log("TopDict: " + topDict);
+
+    // Read the String Index
+    dump("Reading Index: Strings");
+    var strings = readFontIndexData(aStream);
+    log("strings: " + strings);
+
+    // Fill up the Strings dictionary with the new unique strings
+    for (var i = 0; i < strings.length; i++)
+      CFFStrings.push(strings[i].join(""));
+
+    // Parse the TopDict operator
+    var objects = [];
+    var count = topDict.length;
+    for (var i = 0; i < count; i++)
+      parseAsToken(topDict[i], CFFDictDataMap);
+
+    // Read the Global Subr Index that comes just after the Strings Index
+    // (cf. "The Compact Font Format Specification" Chapter 16)
+    dump("Reading Global Subr Index");
+    var subrs = readFontIndexData(aStream, true);
+    dump(subrs);
+
+    // Reading Private Dict
+    var private = font.get("Private");
+    log("Reading Private Dict (offset: " + private.offset + " size: " + private.size + ")");
+    aStream.pos = private.offset;
+
+    var privateDict = [];
+    for (var i = 0; i < private.size; i++)
+      privateDict.push(aStream.getByte());
+    dump("private:" + privateDict);
+    parseAsToken(privateDict, CFFDictPrivateDataMap);
+
+    for (var p in font.map)
+      dump(p + "::" + font.get(p));
+
+    // Read CharStrings Index
+    var charStringsOffset = font.get("CharStrings");
+    dump("Read CharStrings Index (offset: " + charStringsOffset + ")");
+    aStream.pos = charStringsOffset;
+    var charStrings = readFontIndexData(aStream, true);
+
+    // Read Charset
+    dump("Read Charset for " + charStrings.length + " glyphs");
+    var charsetEntry = font.get("charset");
+    if (charsetEntry == 0) {
+      error("Need to support CFFISOAdobeCharset");
+    } else if (charsetEntry == 1) {
+      error("Need to support CFFExpert");
+    } else if (charsetEntry == 2) {
+      error("Need to support CFFExpertSubsetCharset");
+    } else {
+      aStream.pos = charsetEntry;
+      var charset = readCharset(aStream, charStrings);
+    }
+  }
+};
+
+/*
+ * To try the Type2 decoder on a local file in the current directory:
+ *
+ *  var cff = new Type2Parser("file.cff");
+ *  cff.parse(this.data);
+ *
+ * To try the Type2 decoder on a custom built CFF array:
+ *
+ *  var file = new Uint8Array(cffFileArray, 0, cffFileSize);
+ *  var parser = new Type2Parser();
+ *  parser.parse(new Stream(file));
+ *
+ */
+
+
+/**
+ * Write to a file to the disk (works only on Firefox in privilege mode)
+ * but this is useful for dumping a font file to the disk and check with
+ * fontforge or the ots program what's wrong with the file.
+ *
+ * writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".cff");
+ */
+function writeToFile(aBytes, aFilePath) {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var Cc = Components.classes,
+      Ci = Components.interfaces;
+  var file  = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
+  file.initWithPath(aFilePath);
+
+  var stream = Cc["@mozilla.org/network/file-output-stream;1"]
+                 .createInstance(Ci.nsIFileOutputStream);
+  stream.init(file, 0x04 | 0x08 | 0x20, 0600, 0);
+
+  var bos = Cc["@mozilla.org/binaryoutputstream;1"]
+              .createInstance(Ci.nsIBinaryOutputStream);
+  bos.setOutputStream(stream);
+  bos.writeByteArray(aBytes, aBytes.length);
+  stream.close();
+};
+
diff --git a/glyphlist.js b/glyphlist.js
new file mode 100644
index 000000000..f5a11b522
--- /dev/null
+++ b/glyphlist.js
@@ -0,0 +1,4289 @@
+var GlyphsUnicode = {
+  A: 0x0041,
+  AE: 0x00C6,
+  AEacute: 0x01FC,
+  AEmacron: 0x01E2,
+  AEsmall: 0xF7E6,
+  Aacute: 0x00C1,
+  Aacutesmall: 0xF7E1,
+  Abreve: 0x0102,
+  Abreveacute: 0x1EAE,
+  Abrevecyrillic: 0x04D0,
+  Abrevedotbelow: 0x1EB6,
+  Abrevegrave: 0x1EB0,
+  Abrevehookabove: 0x1EB2,
+  Abrevetilde: 0x1EB4,
+  Acaron: 0x01CD,
+  Acircle: 0x24B6,
+  Acircumflex: 0x00C2,
+  Acircumflexacute: 0x1EA4,
+  Acircumflexdotbelow: 0x1EAC,
+  Acircumflexgrave: 0x1EA6,
+  Acircumflexhookabove: 0x1EA8,
+  Acircumflexsmall: 0xF7E2,
+  Acircumflextilde: 0x1EAA,
+  Acute: 0xF6C9,
+  Acutesmall: 0xF7B4,
+  Acyrillic: 0x0410,
+  Adblgrave: 0x0200,
+  Adieresis: 0x00C4,
+  Adieresiscyrillic: 0x04D2,
+  Adieresismacron: 0x01DE,
+  Adieresissmall: 0xF7E4,
+  Adotbelow: 0x1EA0,
+  Adotmacron: 0x01E0,
+  Agrave: 0x00C0,
+  Agravesmall: 0xF7E0,
+  Ahookabove: 0x1EA2,
+  Aiecyrillic: 0x04D4,
+  Ainvertedbreve: 0x0202,
+  Alpha: 0x0391,
+  Alphatonos: 0x0386,
+  Amacron: 0x0100,
+  Amonospace: 0xFF21,
+  Aogonek: 0x0104,
+  Aring: 0x00C5,
+  Aringacute: 0x01FA,
+  Aringbelow: 0x1E00,
+  Aringsmall: 0xF7E5,
+  Asmall: 0xF761,
+  Atilde: 0x00C3,
+  Atildesmall: 0xF7E3,
+  Aybarmenian: 0x0531,
+  B: 0x0042,
+  Bcircle: 0x24B7,
+  Bdotaccent: 0x1E02,
+  Bdotbelow: 0x1E04,
+  Becyrillic: 0x0411,
+  Benarmenian: 0x0532,
+  Beta: 0x0392,
+  Bhook: 0x0181,
+  Blinebelow: 0x1E06,
+  Bmonospace: 0xFF22,
+  Brevesmall: 0xF6F4,
+  Bsmall: 0xF762,
+  Btopbar: 0x0182,
+  C: 0x0043,
+  Caarmenian: 0x053E,
+  Cacute: 0x0106,
+  Caron: 0xF6CA,
+  Caronsmall: 0xF6F5,
+  Ccaron: 0x010C,
+  Ccedilla: 0x00C7,
+  Ccedillaacute: 0x1E08,
+  Ccedillasmall: 0xF7E7,
+  Ccircle: 0x24B8,
+  Ccircumflex: 0x0108,
+  Cdot: 0x010A,
+  Cdotaccent: 0x010A,
+  Cedillasmall: 0xF7B8,
+  Chaarmenian: 0x0549,
+  Cheabkhasiancyrillic: 0x04BC,
+  Checyrillic: 0x0427,
+  Chedescenderabkhasiancyrillic: 0x04BE,
+  Chedescendercyrillic: 0x04B6,
+  Chedieresiscyrillic: 0x04F4,
+  Cheharmenian: 0x0543,
+  Chekhakassiancyrillic: 0x04CB,
+  Cheverticalstrokecyrillic: 0x04B8,
+  Chi: 0x03A7,
+  Chook: 0x0187,
+  Circumflexsmall: 0xF6F6,
+  Cmonospace: 0xFF23,
+  Coarmenian: 0x0551,
+  Csmall: 0xF763,
+  D: 0x0044,
+  DZ: 0x01F1,
+  DZcaron: 0x01C4,
+  Daarmenian: 0x0534,
+  Dafrican: 0x0189,
+  Dcaron: 0x010E,
+  Dcedilla: 0x1E10,
+  Dcircle: 0x24B9,
+  Dcircumflexbelow: 0x1E12,
+  Dcroat: 0x0110,
+  Ddotaccent: 0x1E0A,
+  Ddotbelow: 0x1E0C,
+  Decyrillic: 0x0414,
+  Deicoptic: 0x03EE,
+  Delta: 0x2206,
+  Deltagreek: 0x0394,
+  Dhook: 0x018A,
+  Dieresis: 0xF6CB,
+  DieresisAcute: 0xF6CC,
+  DieresisGrave: 0xF6CD,
+  Dieresissmall: 0xF7A8,
+  Digammagreek: 0x03DC,
+  Djecyrillic: 0x0402,
+  Dlinebelow: 0x1E0E,
+  Dmonospace: 0xFF24,
+  Dotaccentsmall: 0xF6F7,
+  Dslash: 0x0110,
+  Dsmall: 0xF764,
+  Dtopbar: 0x018B,
+  Dz: 0x01F2,
+  Dzcaron: 0x01C5,
+  Dzeabkhasiancyrillic: 0x04E0,
+  Dzecyrillic: 0x0405,
+  Dzhecyrillic: 0x040F,
+  E: 0x0045,
+  Eacute: 0x00C9,
+  Eacutesmall: 0xF7E9,
+  Ebreve: 0x0114,
+  Ecaron: 0x011A,
+  Ecedillabreve: 0x1E1C,
+  Echarmenian: 0x0535,
+  Ecircle: 0x24BA,
+  Ecircumflex: 0x00CA,
+  Ecircumflexacute: 0x1EBE,
+  Ecircumflexbelow: 0x1E18,
+  Ecircumflexdotbelow: 0x1EC6,
+  Ecircumflexgrave: 0x1EC0,
+  Ecircumflexhookabove: 0x1EC2,
+  Ecircumflexsmall: 0xF7EA,
+  Ecircumflextilde: 0x1EC4,
+  Ecyrillic: 0x0404,
+  Edblgrave: 0x0204,
+  Edieresis: 0x00CB,
+  Edieresissmall: 0xF7EB,
+  Edot: 0x0116,
+  Edotaccent: 0x0116,
+  Edotbelow: 0x1EB8,
+  Efcyrillic: 0x0424,
+  Egrave: 0x00C8,
+  Egravesmall: 0xF7E8,
+  Eharmenian: 0x0537,
+  Ehookabove: 0x1EBA,
+  Eightroman: 0x2167,
+  Einvertedbreve: 0x0206,
+  Eiotifiedcyrillic: 0x0464,
+  Elcyrillic: 0x041B,
+  Elevenroman: 0x216A,
+  Emacron: 0x0112,
+  Emacronacute: 0x1E16,
+  Emacrongrave: 0x1E14,
+  Emcyrillic: 0x041C,
+  Emonospace: 0xFF25,
+  Encyrillic: 0x041D,
+  Endescendercyrillic: 0x04A2,
+  Eng: 0x014A,
+  Enghecyrillic: 0x04A4,
+  Enhookcyrillic: 0x04C7,
+  Eogonek: 0x0118,
+  Eopen: 0x0190,
+  Epsilon: 0x0395,
+  Epsilontonos: 0x0388,
+  Ercyrillic: 0x0420,
+  Ereversed: 0x018E,
+  Ereversedcyrillic: 0x042D,
+  Escyrillic: 0x0421,
+  Esdescendercyrillic: 0x04AA,
+  Esh: 0x01A9,
+  Esmall: 0xF765,
+  Eta: 0x0397,
+  Etarmenian: 0x0538,
+  Etatonos: 0x0389,
+  Eth: 0x00D0,
+  Ethsmall: 0xF7F0,
+  Etilde: 0x1EBC,
+  Etildebelow: 0x1E1A,
+  Euro: 0x20AC,
+  Ezh: 0x01B7,
+  Ezhcaron: 0x01EE,
+  Ezhreversed: 0x01B8,
+  F: 0x0046,
+  Fcircle: 0x24BB,
+  Fdotaccent: 0x1E1E,
+  Feharmenian: 0x0556,
+  Feicoptic: 0x03E4,
+  Fhook: 0x0191,
+  Fitacyrillic: 0x0472,
+  Fiveroman: 0x2164,
+  Fmonospace: 0xFF26,
+  Fourroman: 0x2163,
+  Fsmall: 0xF766,
+  G: 0x0047,
+  GBsquare: 0x3387,
+  Gacute: 0x01F4,
+  Gamma: 0x0393,
+  Gammaafrican: 0x0194,
+  Gangiacoptic: 0x03EA,
+  Gbreve: 0x011E,
+  Gcaron: 0x01E6,
+  Gcedilla: 0x0122,
+  Gcircle: 0x24BC,
+  Gcircumflex: 0x011C,
+  Gcommaaccent: 0x0122,
+  Gdot: 0x0120,
+  Gdotaccent: 0x0120,
+  Gecyrillic: 0x0413,
+  Ghadarmenian: 0x0542,
+  Ghemiddlehookcyrillic: 0x0494,
+  Ghestrokecyrillic: 0x0492,
+  Gheupturncyrillic: 0x0490,
+  Ghook: 0x0193,
+  Gimarmenian: 0x0533,
+  Gjecyrillic: 0x0403,
+  Gmacron: 0x1E20,
+  Gmonospace: 0xFF27,
+  Grave: 0xF6CE,
+  Gravesmall: 0xF760,
+  Gsmall: 0xF767,
+  Gsmallhook: 0x029B,
+  Gstroke: 0x01E4,
+  H: 0x0048,
+  H18533: 0x25CF,
+  H18543: 0x25AA,
+  H18551: 0x25AB,
+  H22073: 0x25A1,
+  HPsquare: 0x33CB,
+  Haabkhasiancyrillic: 0x04A8,
+  Hadescendercyrillic: 0x04B2,
+  Hardsigncyrillic: 0x042A,
+  Hbar: 0x0126,
+  Hbrevebelow: 0x1E2A,
+  Hcedilla: 0x1E28,
+  Hcircle: 0x24BD,
+  Hcircumflex: 0x0124,
+  Hdieresis: 0x1E26,
+  Hdotaccent: 0x1E22,
+  Hdotbelow: 0x1E24,
+  Hmonospace: 0xFF28,
+  Hoarmenian: 0x0540,
+  Horicoptic: 0x03E8,
+  Hsmall: 0xF768,
+  Hungarumlaut: 0xF6CF,
+  Hungarumlautsmall: 0xF6F8,
+  Hzsquare: 0x3390,
+  I: 0x0049,
+  IAcyrillic: 0x042F,
+  IJ: 0x0132,
+  IUcyrillic: 0x042E,
+  Iacute: 0x00CD,
+  Iacutesmall: 0xF7ED,
+  Ibreve: 0x012C,
+  Icaron: 0x01CF,
+  Icircle: 0x24BE,
+  Icircumflex: 0x00CE,
+  Icircumflexsmall: 0xF7EE,
+  Icyrillic: 0x0406,
+  Idblgrave: 0x0208,
+  Idieresis: 0x00CF,
+  Idieresisacute: 0x1E2E,
+  Idieresiscyrillic: 0x04E4,
+  Idieresissmall: 0xF7EF,
+  Idot: 0x0130,
+  Idotaccent: 0x0130,
+  Idotbelow: 0x1ECA,
+  Iebrevecyrillic: 0x04D6,
+  Iecyrillic: 0x0415,
+  Ifraktur: 0x2111,
+  Igrave: 0x00CC,
+  Igravesmall: 0xF7EC,
+  Ihookabove: 0x1EC8,
+  Iicyrillic: 0x0418,
+  Iinvertedbreve: 0x020A,
+  Iishortcyrillic: 0x0419,
+  Imacron: 0x012A,
+  Imacroncyrillic: 0x04E2,
+  Imonospace: 0xFF29,
+  Iniarmenian: 0x053B,
+  Iocyrillic: 0x0401,
+  Iogonek: 0x012E,
+  Iota: 0x0399,
+  Iotaafrican: 0x0196,
+  Iotadieresis: 0x03AA,
+  Iotatonos: 0x038A,
+  Ismall: 0xF769,
+  Istroke: 0x0197,
+  Itilde: 0x0128,
+  Itildebelow: 0x1E2C,
+  Izhitsacyrillic: 0x0474,
+  Izhitsadblgravecyrillic: 0x0476,
+  J: 0x004A,
+  Jaarmenian: 0x0541,
+  Jcircle: 0x24BF,
+  Jcircumflex: 0x0134,
+  Jecyrillic: 0x0408,
+  Jheharmenian: 0x054B,
+  Jmonospace: 0xFF2A,
+  Jsmall: 0xF76A,
+  K: 0x004B,
+  KBsquare: 0x3385,
+  KKsquare: 0x33CD,
+  Kabashkircyrillic: 0x04A0,
+  Kacute: 0x1E30,
+  Kacyrillic: 0x041A,
+  Kadescendercyrillic: 0x049A,
+  Kahookcyrillic: 0x04C3,
+  Kappa: 0x039A,
+  Kastrokecyrillic: 0x049E,
+  Kaverticalstrokecyrillic: 0x049C,
+  Kcaron: 0x01E8,
+  Kcedilla: 0x0136,
+  Kcircle: 0x24C0,
+  Kcommaaccent: 0x0136,
+  Kdotbelow: 0x1E32,
+  Keharmenian: 0x0554,
+  Kenarmenian: 0x053F,
+  Khacyrillic: 0x0425,
+  Kheicoptic: 0x03E6,
+  Khook: 0x0198,
+  Kjecyrillic: 0x040C,
+  Klinebelow: 0x1E34,
+  Kmonospace: 0xFF2B,
+  Koppacyrillic: 0x0480,
+  Koppagreek: 0x03DE,
+  Ksicyrillic: 0x046E,
+  Ksmall: 0xF76B,
+  L: 0x004C,
+  LJ: 0x01C7,
+  LL: 0xF6BF,
+  Lacute: 0x0139,
+  Lambda: 0x039B,
+  Lcaron: 0x013D,
+  Lcedilla: 0x013B,
+  Lcircle: 0x24C1,
+  Lcircumflexbelow: 0x1E3C,
+  Lcommaaccent: 0x013B,
+  Ldot: 0x013F,
+  Ldotaccent: 0x013F,
+  Ldotbelow: 0x1E36,
+  Ldotbelowmacron: 0x1E38,
+  Liwnarmenian: 0x053C,
+  Lj: 0x01C8,
+  Ljecyrillic: 0x0409,
+  Llinebelow: 0x1E3A,
+  Lmonospace: 0xFF2C,
+  Lslash: 0x0141,
+  Lslashsmall: 0xF6F9,
+  Lsmall: 0xF76C,
+  M: 0x004D,
+  MBsquare: 0x3386,
+  Macron: 0xF6D0,
+  Macronsmall: 0xF7AF,
+  Macute: 0x1E3E,
+  Mcircle: 0x24C2,
+  Mdotaccent: 0x1E40,
+  Mdotbelow: 0x1E42,
+  Menarmenian: 0x0544,
+  Mmonospace: 0xFF2D,
+  Msmall: 0xF76D,
+  Mturned: 0x019C,
+  Mu: 0x039C,
+  N: 0x004E,
+  NJ: 0x01CA,
+  Nacute: 0x0143,
+  Ncaron: 0x0147,
+  Ncedilla: 0x0145,
+  Ncircle: 0x24C3,
+  Ncircumflexbelow: 0x1E4A,
+  Ncommaaccent: 0x0145,
+  Ndotaccent: 0x1E44,
+  Ndotbelow: 0x1E46,
+  Nhookleft: 0x019D,
+  Nineroman: 0x2168,
+  Nj: 0x01CB,
+  Njecyrillic: 0x040A,
+  Nlinebelow: 0x1E48,
+  Nmonospace: 0xFF2E,
+  Nowarmenian: 0x0546,
+  Nsmall: 0xF76E,
+  Ntilde: 0x00D1,
+  Ntildesmall: 0xF7F1,
+  Nu: 0x039D,
+  O: 0x004F,
+  OE: 0x0152,
+  OEsmall: 0xF6FA,
+  Oacute: 0x00D3,
+  Oacutesmall: 0xF7F3,
+  Obarredcyrillic: 0x04E8,
+  Obarreddieresiscyrillic: 0x04EA,
+  Obreve: 0x014E,
+  Ocaron: 0x01D1,
+  Ocenteredtilde: 0x019F,
+  Ocircle: 0x24C4,
+  Ocircumflex: 0x00D4,
+  Ocircumflexacute: 0x1ED0,
+  Ocircumflexdotbelow: 0x1ED8,
+  Ocircumflexgrave: 0x1ED2,
+  Ocircumflexhookabove: 0x1ED4,
+  Ocircumflexsmall: 0xF7F4,
+  Ocircumflextilde: 0x1ED6,
+  Ocyrillic: 0x041E,
+  Odblacute: 0x0150,
+  Odblgrave: 0x020C,
+  Odieresis: 0x00D6,
+  Odieresiscyrillic: 0x04E6,
+  Odieresissmall: 0xF7F6,
+  Odotbelow: 0x1ECC,
+  Ogoneksmall: 0xF6FB,
+  Ograve: 0x00D2,
+  Ogravesmall: 0xF7F2,
+  Oharmenian: 0x0555,
+  Ohm: 0x2126,
+  Ohookabove: 0x1ECE,
+  Ohorn: 0x01A0,
+  Ohornacute: 0x1EDA,
+  Ohorndotbelow: 0x1EE2,
+  Ohorngrave: 0x1EDC,
+  Ohornhookabove: 0x1EDE,
+  Ohorntilde: 0x1EE0,
+  Ohungarumlaut: 0x0150,
+  Oi: 0x01A2,
+  Oinvertedbreve: 0x020E,
+  Omacron: 0x014C,
+  Omacronacute: 0x1E52,
+  Omacrongrave: 0x1E50,
+  Omega: 0x2126,
+  Omegacyrillic: 0x0460,
+  Omegagreek: 0x03A9,
+  Omegaroundcyrillic: 0x047A,
+  Omegatitlocyrillic: 0x047C,
+  Omegatonos: 0x038F,
+  Omicron: 0x039F,
+  Omicrontonos: 0x038C,
+  Omonospace: 0xFF2F,
+  Oneroman: 0x2160,
+  Oogonek: 0x01EA,
+  Oogonekmacron: 0x01EC,
+  Oopen: 0x0186,
+  Oslash: 0x00D8,
+  Oslashacute: 0x01FE,
+  Oslashsmall: 0xF7F8,
+  Osmall: 0xF76F,
+  Ostrokeacute: 0x01FE,
+  Otcyrillic: 0x047E,
+  Otilde: 0x00D5,
+  Otildeacute: 0x1E4C,
+  Otildedieresis: 0x1E4E,
+  Otildesmall: 0xF7F5,
+  P: 0x0050,
+  Pacute: 0x1E54,
+  Pcircle: 0x24C5,
+  Pdotaccent: 0x1E56,
+  Pecyrillic: 0x041F,
+  Peharmenian: 0x054A,
+  Pemiddlehookcyrillic: 0x04A6,
+  Phi: 0x03A6,
+  Phook: 0x01A4,
+  Pi: 0x03A0,
+  Piwrarmenian: 0x0553,
+  Pmonospace: 0xFF30,
+  Psi: 0x03A8,
+  Psicyrillic: 0x0470,
+  Psmall: 0xF770,
+  Q: 0x0051,
+  Qcircle: 0x24C6,
+  Qmonospace: 0xFF31,
+  Qsmall: 0xF771,
+  R: 0x0052,
+  Raarmenian: 0x054C,
+  Racute: 0x0154,
+  Rcaron: 0x0158,
+  Rcedilla: 0x0156,
+  Rcircle: 0x24C7,
+  Rcommaaccent: 0x0156,
+  Rdblgrave: 0x0210,
+  Rdotaccent: 0x1E58,
+  Rdotbelow: 0x1E5A,
+  Rdotbelowmacron: 0x1E5C,
+  Reharmenian: 0x0550,
+  Rfraktur: 0x211C,
+  Rho: 0x03A1,
+  Ringsmall: 0xF6FC,
+  Rinvertedbreve: 0x0212,
+  Rlinebelow: 0x1E5E,
+  Rmonospace: 0xFF32,
+  Rsmall: 0xF772,
+  Rsmallinverted: 0x0281,
+  Rsmallinvertedsuperior: 0x02B6,
+  S: 0x0053,
+  SF010000: 0x250C,
+  SF020000: 0x2514,
+  SF030000: 0x2510,
+  SF040000: 0x2518,
+  SF050000: 0x253C,
+  SF060000: 0x252C,
+  SF070000: 0x2534,
+  SF080000: 0x251C,
+  SF090000: 0x2524,
+  SF100000: 0x2500,
+  SF110000: 0x2502,
+  SF190000: 0x2561,
+  SF200000: 0x2562,
+  SF210000: 0x2556,
+  SF220000: 0x2555,
+  SF230000: 0x2563,
+  SF240000: 0x2551,
+  SF250000: 0x2557,
+  SF260000: 0x255D,
+  SF270000: 0x255C,
+  SF280000: 0x255B,
+  SF360000: 0x255E,
+  SF370000: 0x255F,
+  SF380000: 0x255A,
+  SF390000: 0x2554,
+  SF400000: 0x2569,
+  SF410000: 0x2566,
+  SF420000: 0x2560,
+  SF430000: 0x2550,
+  SF440000: 0x256C,
+  SF450000: 0x2567,
+  SF460000: 0x2568,
+  SF470000: 0x2564,
+  SF480000: 0x2565,
+  SF490000: 0x2559,
+  SF500000: 0x2558,
+  SF510000: 0x2552,
+  SF520000: 0x2553,
+  SF530000: 0x256B,
+  SF540000: 0x256A,
+  Sacute: 0x015A,
+  Sacutedotaccent: 0x1E64,
+  Sampigreek: 0x03E0,
+  Scaron: 0x0160,
+  Scarondotaccent: 0x1E66,
+  Scaronsmall: 0xF6FD,
+  Scedilla: 0x015E,
+  Schwa: 0x018F,
+  Schwacyrillic: 0x04D8,
+  Schwadieresiscyrillic: 0x04DA,
+  Scircle: 0x24C8,
+  Scircumflex: 0x015C,
+  Scommaaccent: 0x0218,
+  Sdotaccent: 0x1E60,
+  Sdotbelow: 0x1E62,
+  Sdotbelowdotaccent: 0x1E68,
+  Seharmenian: 0x054D,
+  Sevenroman: 0x2166,
+  Shaarmenian: 0x0547,
+  Shacyrillic: 0x0428,
+  Shchacyrillic: 0x0429,
+  Sheicoptic: 0x03E2,
+  Shhacyrillic: 0x04BA,
+  Shimacoptic: 0x03EC,
+  Sigma: 0x03A3,
+  Sixroman: 0x2165,
+  Smonospace: 0xFF33,
+  Softsigncyrillic: 0x042C,
+  Ssmall: 0xF773,
+  Stigmagreek: 0x03DA,
+  T: 0x0054,
+  Tau: 0x03A4,
+  Tbar: 0x0166,
+  Tcaron: 0x0164,
+  Tcedilla: 0x0162,
+  Tcircle: 0x24C9,
+  Tcircumflexbelow: 0x1E70,
+  Tcommaaccent: 0x0162,
+  Tdotaccent: 0x1E6A,
+  Tdotbelow: 0x1E6C,
+  Tecyrillic: 0x0422,
+  Tedescendercyrillic: 0x04AC,
+  Tenroman: 0x2169,
+  Tetsecyrillic: 0x04B4,
+  Theta: 0x0398,
+  Thook: 0x01AC,
+  Thorn: 0x00DE,
+  Thornsmall: 0xF7FE,
+  Threeroman: 0x2162,
+  Tildesmall: 0xF6FE,
+  Tiwnarmenian: 0x054F,
+  Tlinebelow: 0x1E6E,
+  Tmonospace: 0xFF34,
+  Toarmenian: 0x0539,
+  Tonefive: 0x01BC,
+  Tonesix: 0x0184,
+  Tonetwo: 0x01A7,
+  Tretroflexhook: 0x01AE,
+  Tsecyrillic: 0x0426,
+  Tshecyrillic: 0x040B,
+  Tsmall: 0xF774,
+  Twelveroman: 0x216B,
+  Tworoman: 0x2161,
+  U: 0x0055,
+  Uacute: 0x00DA,
+  Uacutesmall: 0xF7FA,
+  Ubreve: 0x016C,
+  Ucaron: 0x01D3,
+  Ucircle: 0x24CA,
+  Ucircumflex: 0x00DB,
+  Ucircumflexbelow: 0x1E76,
+  Ucircumflexsmall: 0xF7FB,
+  Ucyrillic: 0x0423,
+  Udblacute: 0x0170,
+  Udblgrave: 0x0214,
+  Udieresis: 0x00DC,
+  Udieresisacute: 0x01D7,
+  Udieresisbelow: 0x1E72,
+  Udieresiscaron: 0x01D9,
+  Udieresiscyrillic: 0x04F0,
+  Udieresisgrave: 0x01DB,
+  Udieresismacron: 0x01D5,
+  Udieresissmall: 0xF7FC,
+  Udotbelow: 0x1EE4,
+  Ugrave: 0x00D9,
+  Ugravesmall: 0xF7F9,
+  Uhookabove: 0x1EE6,
+  Uhorn: 0x01AF,
+  Uhornacute: 0x1EE8,
+  Uhorndotbelow: 0x1EF0,
+  Uhorngrave: 0x1EEA,
+  Uhornhookabove: 0x1EEC,
+  Uhorntilde: 0x1EEE,
+  Uhungarumlaut: 0x0170,
+  Uhungarumlautcyrillic: 0x04F2,
+  Uinvertedbreve: 0x0216,
+  Ukcyrillic: 0x0478,
+  Umacron: 0x016A,
+  Umacroncyrillic: 0x04EE,
+  Umacrondieresis: 0x1E7A,
+  Umonospace: 0xFF35,
+  Uogonek: 0x0172,
+  Upsilon: 0x03A5,
+  Upsilon1: 0x03D2,
+  Upsilonacutehooksymbolgreek: 0x03D3,
+  Upsilonafrican: 0x01B1,
+  Upsilondieresis: 0x03AB,
+  Upsilondieresishooksymbolgreek: 0x03D4,
+  Upsilonhooksymbol: 0x03D2,
+  Upsilontonos: 0x038E,
+  Uring: 0x016E,
+  Ushortcyrillic: 0x040E,
+  Usmall: 0xF775,
+  Ustraightcyrillic: 0x04AE,
+  Ustraightstrokecyrillic: 0x04B0,
+  Utilde: 0x0168,
+  Utildeacute: 0x1E78,
+  Utildebelow: 0x1E74,
+  V: 0x0056,
+  Vcircle: 0x24CB,
+  Vdotbelow: 0x1E7E,
+  Vecyrillic: 0x0412,
+  Vewarmenian: 0x054E,
+  Vhook: 0x01B2,
+  Vmonospace: 0xFF36,
+  Voarmenian: 0x0548,
+  Vsmall: 0xF776,
+  Vtilde: 0x1E7C,
+  W: 0x0057,
+  Wacute: 0x1E82,
+  Wcircle: 0x24CC,
+  Wcircumflex: 0x0174,
+  Wdieresis: 0x1E84,
+  Wdotaccent: 0x1E86,
+  Wdotbelow: 0x1E88,
+  Wgrave: 0x1E80,
+  Wmonospace: 0xFF37,
+  Wsmall: 0xF777,
+  X: 0x0058,
+  Xcircle: 0x24CD,
+  Xdieresis: 0x1E8C,
+  Xdotaccent: 0x1E8A,
+  Xeharmenian: 0x053D,
+  Xi: 0x039E,
+  Xmonospace: 0xFF38,
+  Xsmall: 0xF778,
+  Y: 0x0059,
+  Yacute: 0x00DD,
+  Yacutesmall: 0xF7FD,
+  Yatcyrillic: 0x0462,
+  Ycircle: 0x24CE,
+  Ycircumflex: 0x0176,
+  Ydieresis: 0x0178,
+  Ydieresissmall: 0xF7FF,
+  Ydotaccent: 0x1E8E,
+  Ydotbelow: 0x1EF4,
+  Yericyrillic: 0x042B,
+  Yerudieresiscyrillic: 0x04F8,
+  Ygrave: 0x1EF2,
+  Yhook: 0x01B3,
+  Yhookabove: 0x1EF6,
+  Yiarmenian: 0x0545,
+  Yicyrillic: 0x0407,
+  Yiwnarmenian: 0x0552,
+  Ymonospace: 0xFF39,
+  Ysmall: 0xF779,
+  Ytilde: 0x1EF8,
+  Yusbigcyrillic: 0x046A,
+  Yusbigiotifiedcyrillic: 0x046C,
+  Yuslittlecyrillic: 0x0466,
+  Yuslittleiotifiedcyrillic: 0x0468,
+  Z: 0x005A,
+  Zaarmenian: 0x0536,
+  Zacute: 0x0179,
+  Zcaron: 0x017D,
+  Zcaronsmall: 0xF6FF,
+  Zcircle: 0x24CF,
+  Zcircumflex: 0x1E90,
+  Zdot: 0x017B,
+  Zdotaccent: 0x017B,
+  Zdotbelow: 0x1E92,
+  Zecyrillic: 0x0417,
+  Zedescendercyrillic: 0x0498,
+  Zedieresiscyrillic: 0x04DE,
+  Zeta: 0x0396,
+  Zhearmenian: 0x053A,
+  Zhebrevecyrillic: 0x04C1,
+  Zhecyrillic: 0x0416,
+  Zhedescendercyrillic: 0x0496,
+  Zhedieresiscyrillic: 0x04DC,
+  Zlinebelow: 0x1E94,
+  Zmonospace: 0xFF3A,
+  Zsmall: 0xF77A,
+  Zstroke: 0x01B5,
+  a: 0x0061,
+  aabengali: 0x0986,
+  aacute: 0x00E1,
+  aadeva: 0x0906,
+  aagujarati: 0x0A86,
+  aagurmukhi: 0x0A06,
+  aamatragurmukhi: 0x0A3E,
+  aarusquare: 0x3303,
+  aavowelsignbengali: 0x09BE,
+  aavowelsigndeva: 0x093E,
+  aavowelsigngujarati: 0x0ABE,
+  abbreviationmarkarmenian: 0x055F,
+  abbreviationsigndeva: 0x0970,
+  abengali: 0x0985,
+  abopomofo: 0x311A,
+  abreve: 0x0103,
+  abreveacute: 0x1EAF,
+  abrevecyrillic: 0x04D1,
+  abrevedotbelow: 0x1EB7,
+  abrevegrave: 0x1EB1,
+  abrevehookabove: 0x1EB3,
+  abrevetilde: 0x1EB5,
+  acaron: 0x01CE,
+  acircle: 0x24D0,
+  acircumflex: 0x00E2,
+  acircumflexacute: 0x1EA5,
+  acircumflexdotbelow: 0x1EAD,
+  acircumflexgrave: 0x1EA7,
+  acircumflexhookabove: 0x1EA9,
+  acircumflextilde: 0x1EAB,
+  acute: 0x00B4,
+  acutebelowcmb: 0x0317,
+  acutecmb: 0x0301,
+  acutecomb: 0x0301,
+  acutedeva: 0x0954,
+  acutelowmod: 0x02CF,
+  acutetonecmb: 0x0341,
+  acyrillic: 0x0430,
+  adblgrave: 0x0201,
+  addakgurmukhi: 0x0A71,
+  adeva: 0x0905,
+  adieresis: 0x00E4,
+  adieresiscyrillic: 0x04D3,
+  adieresismacron: 0x01DF,
+  adotbelow: 0x1EA1,
+  adotmacron: 0x01E1,
+  ae: 0x00E6,
+  aeacute: 0x01FD,
+  aekorean: 0x3150,
+  aemacron: 0x01E3,
+  afii00208: 0x2015,
+  afii08941: 0x20A4,
+  afii10017: 0x0410,
+  afii10018: 0x0411,
+  afii10019: 0x0412,
+  afii10020: 0x0413,
+  afii10021: 0x0414,
+  afii10022: 0x0415,
+  afii10023: 0x0401,
+  afii10024: 0x0416,
+  afii10025: 0x0417,
+  afii10026: 0x0418,
+  afii10027: 0x0419,
+  afii10028: 0x041A,
+  afii10029: 0x041B,
+  afii10030: 0x041C,
+  afii10031: 0x041D,
+  afii10032: 0x041E,
+  afii10033: 0x041F,
+  afii10034: 0x0420,
+  afii10035: 0x0421,
+  afii10036: 0x0422,
+  afii10037: 0x0423,
+  afii10038: 0x0424,
+  afii10039: 0x0425,
+  afii10040: 0x0426,
+  afii10041: 0x0427,
+  afii10042: 0x0428,
+  afii10043: 0x0429,
+  afii10044: 0x042A,
+  afii10045: 0x042B,
+  afii10046: 0x042C,
+  afii10047: 0x042D,
+  afii10048: 0x042E,
+  afii10049: 0x042F,
+  afii10050: 0x0490,
+  afii10051: 0x0402,
+  afii10052: 0x0403,
+  afii10053: 0x0404,
+  afii10054: 0x0405,
+  afii10055: 0x0406,
+  afii10056: 0x0407,
+  afii10057: 0x0408,
+  afii10058: 0x0409,
+  afii10059: 0x040A,
+  afii10060: 0x040B,
+  afii10061: 0x040C,
+  afii10062: 0x040E,
+  afii10063: 0xF6C4,
+  afii10064: 0xF6C5,
+  afii10065: 0x0430,
+  afii10066: 0x0431,
+  afii10067: 0x0432,
+  afii10068: 0x0433,
+  afii10069: 0x0434,
+  afii10070: 0x0435,
+  afii10071: 0x0451,
+  afii10072: 0x0436,
+  afii10073: 0x0437,
+  afii10074: 0x0438,
+  afii10075: 0x0439,
+  afii10076: 0x043A,
+  afii10077: 0x043B,
+  afii10078: 0x043C,
+  afii10079: 0x043D,
+  afii10080: 0x043E,
+  afii10081: 0x043F,
+  afii10082: 0x0440,
+  afii10083: 0x0441,
+  afii10084: 0x0442,
+  afii10085: 0x0443,
+  afii10086: 0x0444,
+  afii10087: 0x0445,
+  afii10088: 0x0446,
+  afii10089: 0x0447,
+  afii10090: 0x0448,
+  afii10091: 0x0449,
+  afii10092: 0x044A,
+  afii10093: 0x044B,
+  afii10094: 0x044C,
+  afii10095: 0x044D,
+  afii10096: 0x044E,
+  afii10097: 0x044F,
+  afii10098: 0x0491,
+  afii10099: 0x0452,
+  afii10100: 0x0453,
+  afii10101: 0x0454,
+  afii10102: 0x0455,
+  afii10103: 0x0456,
+  afii10104: 0x0457,
+  afii10105: 0x0458,
+  afii10106: 0x0459,
+  afii10107: 0x045A,
+  afii10108: 0x045B,
+  afii10109: 0x045C,
+  afii10110: 0x045E,
+  afii10145: 0x040F,
+  afii10146: 0x0462,
+  afii10147: 0x0472,
+  afii10148: 0x0474,
+  afii10192: 0xF6C6,
+  afii10193: 0x045F,
+  afii10194: 0x0463,
+  afii10195: 0x0473,
+  afii10196: 0x0475,
+  afii10831: 0xF6C7,
+  afii10832: 0xF6C8,
+  afii10846: 0x04D9,
+  afii299: 0x200E,
+  afii300: 0x200F,
+  afii301: 0x200D,
+  afii57381: 0x066A,
+  afii57388: 0x060C,
+  afii57392: 0x0660,
+  afii57393: 0x0661,
+  afii57394: 0x0662,
+  afii57395: 0x0663,
+  afii57396: 0x0664,
+  afii57397: 0x0665,
+  afii57398: 0x0666,
+  afii57399: 0x0667,
+  afii57400: 0x0668,
+  afii57401: 0x0669,
+  afii57403: 0x061B,
+  afii57407: 0x061F,
+  afii57409: 0x0621,
+  afii57410: 0x0622,
+  afii57411: 0x0623,
+  afii57412: 0x0624,
+  afii57413: 0x0625,
+  afii57414: 0x0626,
+  afii57415: 0x0627,
+  afii57416: 0x0628,
+  afii57417: 0x0629,
+  afii57418: 0x062A,
+  afii57419: 0x062B,
+  afii57420: 0x062C,
+  afii57421: 0x062D,
+  afii57422: 0x062E,
+  afii57423: 0x062F,
+  afii57424: 0x0630,
+  afii57425: 0x0631,
+  afii57426: 0x0632,
+  afii57427: 0x0633,
+  afii57428: 0x0634,
+  afii57429: 0x0635,
+  afii57430: 0x0636,
+  afii57431: 0x0637,
+  afii57432: 0x0638,
+  afii57433: 0x0639,
+  afii57434: 0x063A,
+  afii57440: 0x0640,
+  afii57441: 0x0641,
+  afii57442: 0x0642,
+  afii57443: 0x0643,
+  afii57444: 0x0644,
+  afii57445: 0x0645,
+  afii57446: 0x0646,
+  afii57448: 0x0648,
+  afii57449: 0x0649,
+  afii57450: 0x064A,
+  afii57451: 0x064B,
+  afii57452: 0x064C,
+  afii57453: 0x064D,
+  afii57454: 0x064E,
+  afii57455: 0x064F,
+  afii57456: 0x0650,
+  afii57457: 0x0651,
+  afii57458: 0x0652,
+  afii57470: 0x0647,
+  afii57505: 0x06A4,
+  afii57506: 0x067E,
+  afii57507: 0x0686,
+  afii57508: 0x0698,
+  afii57509: 0x06AF,
+  afii57511: 0x0679,
+  afii57512: 0x0688,
+  afii57513: 0x0691,
+  afii57514: 0x06BA,
+  afii57519: 0x06D2,
+  afii57534: 0x06D5,
+  afii57636: 0x20AA,
+  afii57645: 0x05BE,
+  afii57658: 0x05C3,
+  afii57664: 0x05D0,
+  afii57665: 0x05D1,
+  afii57666: 0x05D2,
+  afii57667: 0x05D3,
+  afii57668: 0x05D4,
+  afii57669: 0x05D5,
+  afii57670: 0x05D6,
+  afii57671: 0x05D7,
+  afii57672: 0x05D8,
+  afii57673: 0x05D9,
+  afii57674: 0x05DA,
+  afii57675: 0x05DB,
+  afii57676: 0x05DC,
+  afii57677: 0x05DD,
+  afii57678: 0x05DE,
+  afii57679: 0x05DF,
+  afii57680: 0x05E0,
+  afii57681: 0x05E1,
+  afii57682: 0x05E2,
+  afii57683: 0x05E3,
+  afii57684: 0x05E4,
+  afii57685: 0x05E5,
+  afii57686: 0x05E6,
+  afii57687: 0x05E7,
+  afii57688: 0x05E8,
+  afii57689: 0x05E9,
+  afii57690: 0x05EA,
+  afii57694: 0xFB2A,
+  afii57695: 0xFB2B,
+  afii57700: 0xFB4B,
+  afii57705: 0xFB1F,
+  afii57716: 0x05F0,
+  afii57717: 0x05F1,
+  afii57718: 0x05F2,
+  afii57723: 0xFB35,
+  afii57793: 0x05B4,
+  afii57794: 0x05B5,
+  afii57795: 0x05B6,
+  afii57796: 0x05BB,
+  afii57797: 0x05B8,
+  afii57798: 0x05B7,
+  afii57799: 0x05B0,
+  afii57800: 0x05B2,
+  afii57801: 0x05B1,
+  afii57802: 0x05B3,
+  afii57803: 0x05C2,
+  afii57804: 0x05C1,
+  afii57806: 0x05B9,
+  afii57807: 0x05BC,
+  afii57839: 0x05BD,
+  afii57841: 0x05BF,
+  afii57842: 0x05C0,
+  afii57929: 0x02BC,
+  afii61248: 0x2105,
+  afii61289: 0x2113,
+  afii61352: 0x2116,
+  afii61573: 0x202C,
+  afii61574: 0x202D,
+  afii61575: 0x202E,
+  afii61664: 0x200C,
+  afii63167: 0x066D,
+  afii64937: 0x02BD,
+  agrave: 0x00E0,
+  agujarati: 0x0A85,
+  agurmukhi: 0x0A05,
+  ahiragana: 0x3042,
+  ahookabove: 0x1EA3,
+  aibengali: 0x0990,
+  aibopomofo: 0x311E,
+  aideva: 0x0910,
+  aiecyrillic: 0x04D5,
+  aigujarati: 0x0A90,
+  aigurmukhi: 0x0A10,
+  aimatragurmukhi: 0x0A48,
+  ainarabic: 0x0639,
+  ainfinalarabic: 0xFECA,
+  aininitialarabic: 0xFECB,
+  ainmedialarabic: 0xFECC,
+  ainvertedbreve: 0x0203,
+  aivowelsignbengali: 0x09C8,
+  aivowelsigndeva: 0x0948,
+  aivowelsigngujarati: 0x0AC8,
+  akatakana: 0x30A2,
+  akatakanahalfwidth: 0xFF71,
+  akorean: 0x314F,
+  alef: 0x05D0,
+  alefarabic: 0x0627,
+  alefdageshhebrew: 0xFB30,
+  aleffinalarabic: 0xFE8E,
+  alefhamzaabovearabic: 0x0623,
+  alefhamzaabovefinalarabic: 0xFE84,
+  alefhamzabelowarabic: 0x0625,
+  alefhamzabelowfinalarabic: 0xFE88,
+  alefhebrew: 0x05D0,
+  aleflamedhebrew: 0xFB4F,
+  alefmaddaabovearabic: 0x0622,
+  alefmaddaabovefinalarabic: 0xFE82,
+  alefmaksuraarabic: 0x0649,
+  alefmaksurafinalarabic: 0xFEF0,
+  alefmaksurainitialarabic: 0xFEF3,
+  alefmaksuramedialarabic: 0xFEF4,
+  alefpatahhebrew: 0xFB2E,
+  alefqamatshebrew: 0xFB2F,
+  aleph: 0x2135,
+  allequal: 0x224C,
+  alpha: 0x03B1,
+  alphatonos: 0x03AC,
+  amacron: 0x0101,
+  amonospace: 0xFF41,
+  ampersand: 0x0026,
+  ampersandmonospace: 0xFF06,
+  ampersandsmall: 0xF726,
+  amsquare: 0x33C2,
+  anbopomofo: 0x3122,
+  angbopomofo: 0x3124,
+  angkhankhuthai: 0x0E5A,
+  angle: 0x2220,
+  anglebracketleft: 0x3008,
+  anglebracketleftvertical: 0xFE3F,
+  anglebracketright: 0x3009,
+  anglebracketrightvertical: 0xFE40,
+  angleleft: 0x2329,
+  angleright: 0x232A,
+  angstrom: 0x212B,
+  anoteleia: 0x0387,
+  anudattadeva: 0x0952,
+  anusvarabengali: 0x0982,
+  anusvaradeva: 0x0902,
+  anusvaragujarati: 0x0A82,
+  aogonek: 0x0105,
+  apaatosquare: 0x3300,
+  aparen: 0x249C,
+  apostrophearmenian: 0x055A,
+  apostrophemod: 0x02BC,
+  apple: 0xF8FF,
+  approaches: 0x2250,
+  approxequal: 0x2248,
+  approxequalorimage: 0x2252,
+  approximatelyequal: 0x2245,
+  araeaekorean: 0x318E,
+  araeakorean: 0x318D,
+  arc: 0x2312,
+  arighthalfring: 0x1E9A,
+  aring: 0x00E5,
+  aringacute: 0x01FB,
+  aringbelow: 0x1E01,
+  arrowboth: 0x2194,
+  arrowdashdown: 0x21E3,
+  arrowdashleft: 0x21E0,
+  arrowdashright: 0x21E2,
+  arrowdashup: 0x21E1,
+  arrowdblboth: 0x21D4,
+  arrowdbldown: 0x21D3,
+  arrowdblleft: 0x21D0,
+  arrowdblright: 0x21D2,
+  arrowdblup: 0x21D1,
+  arrowdown: 0x2193,
+  arrowdownleft: 0x2199,
+  arrowdownright: 0x2198,
+  arrowdownwhite: 0x21E9,
+  arrowheaddownmod: 0x02C5,
+  arrowheadleftmod: 0x02C2,
+  arrowheadrightmod: 0x02C3,
+  arrowheadupmod: 0x02C4,
+  arrowhorizex: 0xF8E7,
+  arrowleft: 0x2190,
+  arrowleftdbl: 0x21D0,
+  arrowleftdblstroke: 0x21CD,
+  arrowleftoverright: 0x21C6,
+  arrowleftwhite: 0x21E6,
+  arrowright: 0x2192,
+  arrowrightdblstroke: 0x21CF,
+  arrowrightheavy: 0x279E,
+  arrowrightoverleft: 0x21C4,
+  arrowrightwhite: 0x21E8,
+  arrowtableft: 0x21E4,
+  arrowtabright: 0x21E5,
+  arrowup: 0x2191,
+  arrowupdn: 0x2195,
+  arrowupdnbse: 0x21A8,
+  arrowupdownbase: 0x21A8,
+  arrowupleft: 0x2196,
+  arrowupleftofdown: 0x21C5,
+  arrowupright: 0x2197,
+  arrowupwhite: 0x21E7,
+  arrowvertex: 0xF8E6,
+  asciicircum: 0x005E,
+  asciicircummonospace: 0xFF3E,
+  asciitilde: 0x007E,
+  asciitildemonospace: 0xFF5E,
+  ascript: 0x0251,
+  ascriptturned: 0x0252,
+  asmallhiragana: 0x3041,
+  asmallkatakana: 0x30A1,
+  asmallkatakanahalfwidth: 0xFF67,
+  asterisk: 0x002A,
+  asteriskaltonearabic: 0x066D,
+  asteriskarabic: 0x066D,
+  asteriskmath: 0x2217,
+  asteriskmonospace: 0xFF0A,
+  asterisksmall: 0xFE61,
+  asterism: 0x2042,
+  asuperior: 0xF6E9,
+  asymptoticallyequal: 0x2243,
+  at: 0x0040,
+  atilde: 0x00E3,
+  atmonospace: 0xFF20,
+  atsmall: 0xFE6B,
+  aturned: 0x0250,
+  aubengali: 0x0994,
+  aubopomofo: 0x3120,
+  audeva: 0x0914,
+  augujarati: 0x0A94,
+  augurmukhi: 0x0A14,
+  aulengthmarkbengali: 0x09D7,
+  aumatragurmukhi: 0x0A4C,
+  auvowelsignbengali: 0x09CC,
+  auvowelsigndeva: 0x094C,
+  auvowelsigngujarati: 0x0ACC,
+  avagrahadeva: 0x093D,
+  aybarmenian: 0x0561,
+  ayin: 0x05E2,
+  ayinaltonehebrew: 0xFB20,
+  ayinhebrew: 0x05E2,
+  b: 0x0062,
+  babengali: 0x09AC,
+  backslash: 0x005C,
+  backslashmonospace: 0xFF3C,
+  badeva: 0x092C,
+  bagujarati: 0x0AAC,
+  bagurmukhi: 0x0A2C,
+  bahiragana: 0x3070,
+  bahtthai: 0x0E3F,
+  bakatakana: 0x30D0,
+  bar: 0x007C,
+  barmonospace: 0xFF5C,
+  bbopomofo: 0x3105,
+  bcircle: 0x24D1,
+  bdotaccent: 0x1E03,
+  bdotbelow: 0x1E05,
+  beamedsixteenthnotes: 0x266C,
+  because: 0x2235,
+  becyrillic: 0x0431,
+  beharabic: 0x0628,
+  behfinalarabic: 0xFE90,
+  behinitialarabic: 0xFE91,
+  behiragana: 0x3079,
+  behmedialarabic: 0xFE92,
+  behmeeminitialarabic: 0xFC9F,
+  behmeemisolatedarabic: 0xFC08,
+  behnoonfinalarabic: 0xFC6D,
+  bekatakana: 0x30D9,
+  benarmenian: 0x0562,
+  bet: 0x05D1,
+  beta: 0x03B2,
+  betasymbolgreek: 0x03D0,
+  betdagesh: 0xFB31,
+  betdageshhebrew: 0xFB31,
+  bethebrew: 0x05D1,
+  betrafehebrew: 0xFB4C,
+  bhabengali: 0x09AD,
+  bhadeva: 0x092D,
+  bhagujarati: 0x0AAD,
+  bhagurmukhi: 0x0A2D,
+  bhook: 0x0253,
+  bihiragana: 0x3073,
+  bikatakana: 0x30D3,
+  bilabialclick: 0x0298,
+  bindigurmukhi: 0x0A02,
+  birusquare: 0x3331,
+  blackcircle: 0x25CF,
+  blackdiamond: 0x25C6,
+  blackdownpointingtriangle: 0x25BC,
+  blackleftpointingpointer: 0x25C4,
+  blackleftpointingtriangle: 0x25C0,
+  blacklenticularbracketleft: 0x3010,
+  blacklenticularbracketleftvertical: 0xFE3B,
+  blacklenticularbracketright: 0x3011,
+  blacklenticularbracketrightvertical: 0xFE3C,
+  blacklowerlefttriangle: 0x25E3,
+  blacklowerrighttriangle: 0x25E2,
+  blackrectangle: 0x25AC,
+  blackrightpointingpointer: 0x25BA,
+  blackrightpointingtriangle: 0x25B6,
+  blacksmallsquare: 0x25AA,
+  blacksmilingface: 0x263B,
+  blacksquare: 0x25A0,
+  blackstar: 0x2605,
+  blackupperlefttriangle: 0x25E4,
+  blackupperrighttriangle: 0x25E5,
+  blackuppointingsmalltriangle: 0x25B4,
+  blackuppointingtriangle: 0x25B2,
+  blank: 0x2423,
+  blinebelow: 0x1E07,
+  block: 0x2588,
+  bmonospace: 0xFF42,
+  bobaimaithai: 0x0E1A,
+  bohiragana: 0x307C,
+  bokatakana: 0x30DC,
+  bparen: 0x249D,
+  bqsquare: 0x33C3,
+  braceex: 0xF8F4,
+  braceleft: 0x007B,
+  braceleftbt: 0xF8F3,
+  braceleftmid: 0xF8F2,
+  braceleftmonospace: 0xFF5B,
+  braceleftsmall: 0xFE5B,
+  bracelefttp: 0xF8F1,
+  braceleftvertical: 0xFE37,
+  braceright: 0x007D,
+  bracerightbt: 0xF8FE,
+  bracerightmid: 0xF8FD,
+  bracerightmonospace: 0xFF5D,
+  bracerightsmall: 0xFE5C,
+  bracerighttp: 0xF8FC,
+  bracerightvertical: 0xFE38,
+  bracketleft: 0x005B,
+  bracketleftbt: 0xF8F0,
+  bracketleftex: 0xF8EF,
+  bracketleftmonospace: 0xFF3B,
+  bracketlefttp: 0xF8EE,
+  bracketright: 0x005D,
+  bracketrightbt: 0xF8FB,
+  bracketrightex: 0xF8FA,
+  bracketrightmonospace: 0xFF3D,
+  bracketrighttp: 0xF8F9,
+  breve: 0x02D8,
+  brevebelowcmb: 0x032E,
+  brevecmb: 0x0306,
+  breveinvertedbelowcmb: 0x032F,
+  breveinvertedcmb: 0x0311,
+  breveinverteddoublecmb: 0x0361,
+  bridgebelowcmb: 0x032A,
+  bridgeinvertedbelowcmb: 0x033A,
+  brokenbar: 0x00A6,
+  bstroke: 0x0180,
+  bsuperior: 0xF6EA,
+  btopbar: 0x0183,
+  buhiragana: 0x3076,
+  bukatakana: 0x30D6,
+  bullet: 0x2022,
+  bulletinverse: 0x25D8,
+  bulletoperator: 0x2219,
+  bullseye: 0x25CE,
+  c: 0x0063,
+  caarmenian: 0x056E,
+  cabengali: 0x099A,
+  cacute: 0x0107,
+  cadeva: 0x091A,
+  cagujarati: 0x0A9A,
+  cagurmukhi: 0x0A1A,
+  calsquare: 0x3388,
+  candrabindubengali: 0x0981,
+  candrabinducmb: 0x0310,
+  candrabindudeva: 0x0901,
+  candrabindugujarati: 0x0A81,
+  capslock: 0x21EA,
+  careof: 0x2105,
+  caron: 0x02C7,
+  caronbelowcmb: 0x032C,
+  caroncmb: 0x030C,
+  carriagereturn: 0x21B5,
+  cbopomofo: 0x3118,
+  ccaron: 0x010D,
+  ccedilla: 0x00E7,
+  ccedillaacute: 0x1E09,
+  ccircle: 0x24D2,
+  ccircumflex: 0x0109,
+  ccurl: 0x0255,
+  cdot: 0x010B,
+  cdotaccent: 0x010B,
+  cdsquare: 0x33C5,
+  cedilla: 0x00B8,
+  cedillacmb: 0x0327,
+  cent: 0x00A2,
+  centigrade: 0x2103,
+  centinferior: 0xF6DF,
+  centmonospace: 0xFFE0,
+  centoldstyle: 0xF7A2,
+  centsuperior: 0xF6E0,
+  chaarmenian: 0x0579,
+  chabengali: 0x099B,
+  chadeva: 0x091B,
+  chagujarati: 0x0A9B,
+  chagurmukhi: 0x0A1B,
+  chbopomofo: 0x3114,
+  cheabkhasiancyrillic: 0x04BD,
+  checkmark: 0x2713,
+  checyrillic: 0x0447,
+  chedescenderabkhasiancyrillic: 0x04BF,
+  chedescendercyrillic: 0x04B7,
+  chedieresiscyrillic: 0x04F5,
+  cheharmenian: 0x0573,
+  chekhakassiancyrillic: 0x04CC,
+  cheverticalstrokecyrillic: 0x04B9,
+  chi: 0x03C7,
+  chieuchacirclekorean: 0x3277,
+  chieuchaparenkorean: 0x3217,
+  chieuchcirclekorean: 0x3269,
+  chieuchkorean: 0x314A,
+  chieuchparenkorean: 0x3209,
+  chochangthai: 0x0E0A,
+  chochanthai: 0x0E08,
+  chochingthai: 0x0E09,
+  chochoethai: 0x0E0C,
+  chook: 0x0188,
+  cieucacirclekorean: 0x3276,
+  cieucaparenkorean: 0x3216,
+  cieuccirclekorean: 0x3268,
+  cieuckorean: 0x3148,
+  cieucparenkorean: 0x3208,
+  cieucuparenkorean: 0x321C,
+  circle: 0x25CB,
+  circlemultiply: 0x2297,
+  circleot: 0x2299,
+  circleplus: 0x2295,
+  circlepostalmark: 0x3036,
+  circlewithlefthalfblack: 0x25D0,
+  circlewithrighthalfblack: 0x25D1,
+  circumflex: 0x02C6,
+  circumflexbelowcmb: 0x032D,
+  circumflexcmb: 0x0302,
+  clear: 0x2327,
+  clickalveolar: 0x01C2,
+  clickdental: 0x01C0,
+  clicklateral: 0x01C1,
+  clickretroflex: 0x01C3,
+  club: 0x2663,
+  clubsuitblack: 0x2663,
+  clubsuitwhite: 0x2667,
+  cmcubedsquare: 0x33A4,
+  cmonospace: 0xFF43,
+  cmsquaredsquare: 0x33A0,
+  coarmenian: 0x0581,
+  colon: 0x003A,
+  colonmonetary: 0x20A1,
+  colonmonospace: 0xFF1A,
+  colonsign: 0x20A1,
+  colonsmall: 0xFE55,
+  colontriangularhalfmod: 0x02D1,
+  colontriangularmod: 0x02D0,
+  comma: 0x002C,
+  commaabovecmb: 0x0313,
+  commaaboverightcmb: 0x0315,
+  commaaccent: 0xF6C3,
+  commaarabic: 0x060C,
+  commaarmenian: 0x055D,
+  commainferior: 0xF6E1,
+  commamonospace: 0xFF0C,
+  commareversedabovecmb: 0x0314,
+  commareversedmod: 0x02BD,
+  commasmall: 0xFE50,
+  commasuperior: 0xF6E2,
+  commaturnedabovecmb: 0x0312,
+  commaturnedmod: 0x02BB,
+  compass: 0x263C,
+  congruent: 0x2245,
+  contourintegral: 0x222E,
+  control: 0x2303,
+  controlACK: 0x0006,
+  controlBEL: 0x0007,
+  controlBS: 0x0008,
+  controlCAN: 0x0018,
+  controlCR: 0x000D,
+  controlDC1: 0x0011,
+  controlDC2: 0x0012,
+  controlDC3: 0x0013,
+  controlDC4: 0x0014,
+  controlDEL: 0x007F,
+  controlDLE: 0x0010,
+  controlEM: 0x0019,
+  controlENQ: 0x0005,
+  controlEOT: 0x0004,
+  controlESC: 0x001B,
+  controlETB: 0x0017,
+  controlETX: 0x0003,
+  controlFF: 0x000C,
+  controlFS: 0x001C,
+  controlGS: 0x001D,
+  controlHT: 0x0009,
+  controlLF: 0x000A,
+  controlNAK: 0x0015,
+  controlRS: 0x001E,
+  controlSI: 0x000F,
+  controlSO: 0x000E,
+  controlSOT: 0x0002,
+  controlSTX: 0x0001,
+  controlSUB: 0x001A,
+  controlSYN: 0x0016,
+  controlUS: 0x001F,
+  controlVT: 0x000B,
+  copyright: 0x00A9,
+  copyrightsans: 0xF8E9,
+  copyrightserif: 0xF6D9,
+  cornerbracketleft: 0x300C,
+  cornerbracketlefthalfwidth: 0xFF62,
+  cornerbracketleftvertical: 0xFE41,
+  cornerbracketright: 0x300D,
+  cornerbracketrighthalfwidth: 0xFF63,
+  cornerbracketrightvertical: 0xFE42,
+  corporationsquare: 0x337F,
+  cosquare: 0x33C7,
+  coverkgsquare: 0x33C6,
+  cparen: 0x249E,
+  cruzeiro: 0x20A2,
+  cstretched: 0x0297,
+  curlyand: 0x22CF,
+  curlyor: 0x22CE,
+  currency: 0x00A4,
+  cyrBreve: 0xF6D1,
+  cyrFlex: 0xF6D2,
+  cyrbreve: 0xF6D4,
+  cyrflex: 0xF6D5,
+  d: 0x0064,
+  daarmenian: 0x0564,
+  dabengali: 0x09A6,
+  dadarabic: 0x0636,
+  dadeva: 0x0926,
+  dadfinalarabic: 0xFEBE,
+  dadinitialarabic: 0xFEBF,
+  dadmedialarabic: 0xFEC0,
+  dagesh: 0x05BC,
+  dageshhebrew: 0x05BC,
+  dagger: 0x2020,
+  daggerdbl: 0x2021,
+  dagujarati: 0x0AA6,
+  dagurmukhi: 0x0A26,
+  dahiragana: 0x3060,
+  dakatakana: 0x30C0,
+  dalarabic: 0x062F,
+  dalet: 0x05D3,
+  daletdagesh: 0xFB33,
+  daletdageshhebrew: 0xFB33,
+  dalethatafpatah: "05D3 05B2",
+  dalethatafpatahhebrew: "05D3 05B2",
+  dalethatafsegol: "05D3 05B1",
+  dalethatafsegolhebrew: "05D3 05B1",
+  dalethebrew: 0x05D3,
+  dalethiriq: "05D3 05B4",
+  dalethiriqhebrew: "05D3 05B4",
+  daletholam: "05D3 05B9",
+  daletholamhebrew: "05D3 05B9",
+  daletpatah: "05D3 05B7",
+  daletpatahhebrew: "05D3 05B7",
+  daletqamats: "05D3 05B8",
+  daletqamatshebrew: "05D3 05B8",
+  daletqubuts: "05D3 05BB",
+  daletqubutshebrew: "05D3 05BB",
+  daletsegol: "05D3 05B6",
+  daletsegolhebrew: "05D3 05B6",
+  daletsheva: "05D3 05B0",
+  daletshevahebrew: "05D3 05B0",
+  dalettsere: "05D3 05B5",
+  dalettserehebrew: "05D3 05B5",
+  dalfinalarabic: 0xFEAA,
+  dammaarabic: 0x064F,
+  dammalowarabic: 0x064F,
+  dammatanaltonearabic: 0x064C,
+  dammatanarabic: 0x064C,
+  danda: 0x0964,
+  dargahebrew: 0x05A7,
+  dargalefthebrew: 0x05A7,
+  dasiapneumatacyrilliccmb: 0x0485,
+  dblGrave: 0xF6D3,
+  dblanglebracketleft: 0x300A,
+  dblanglebracketleftvertical: 0xFE3D,
+  dblanglebracketright: 0x300B,
+  dblanglebracketrightvertical: 0xFE3E,
+  dblarchinvertedbelowcmb: 0x032B,
+  dblarrowleft: 0x21D4,
+  dblarrowright: 0x21D2,
+  dbldanda: 0x0965,
+  dblgrave: 0xF6D6,
+  dblgravecmb: 0x030F,
+  dblintegral: 0x222C,
+  dbllowline: 0x2017,
+  dbllowlinecmb: 0x0333,
+  dbloverlinecmb: 0x033F,
+  dblprimemod: 0x02BA,
+  dblverticalbar: 0x2016,
+  dblverticallineabovecmb: 0x030E,
+  dbopomofo: 0x3109,
+  dbsquare: 0x33C8,
+  dcaron: 0x010F,
+  dcedilla: 0x1E11,
+  dcircle: 0x24D3,
+  dcircumflexbelow: 0x1E13,
+  dcroat: 0x0111,
+  ddabengali: 0x09A1,
+  ddadeva: 0x0921,
+  ddagujarati: 0x0AA1,
+  ddagurmukhi: 0x0A21,
+  ddalarabic: 0x0688,
+  ddalfinalarabic: 0xFB89,
+  dddhadeva: 0x095C,
+  ddhabengali: 0x09A2,
+  ddhadeva: 0x0922,
+  ddhagujarati: 0x0AA2,
+  ddhagurmukhi: 0x0A22,
+  ddotaccent: 0x1E0B,
+  ddotbelow: 0x1E0D,
+  decimalseparatorarabic: 0x066B,
+  decimalseparatorpersian: 0x066B,
+  decyrillic: 0x0434,
+  degree: 0x00B0,
+  dehihebrew: 0x05AD,
+  dehiragana: 0x3067,
+  deicoptic: 0x03EF,
+  dekatakana: 0x30C7,
+  deleteleft: 0x232B,
+  deleteright: 0x2326,
+  delta: 0x03B4,
+  deltaturned: 0x018D,
+  denominatorminusonenumeratorbengali: 0x09F8,
+  dezh: 0x02A4,
+  dhabengali: 0x09A7,
+  dhadeva: 0x0927,
+  dhagujarati: 0x0AA7,
+  dhagurmukhi: 0x0A27,
+  dhook: 0x0257,
+  dialytikatonos: 0x0385,
+  dialytikatonoscmb: 0x0344,
+  diamond: 0x2666,
+  diamondsuitwhite: 0x2662,
+  dieresis: 0x00A8,
+  dieresisacute: 0xF6D7,
+  dieresisbelowcmb: 0x0324,
+  dieresiscmb: 0x0308,
+  dieresisgrave: 0xF6D8,
+  dieresistonos: 0x0385,
+  dihiragana: 0x3062,
+  dikatakana: 0x30C2,
+  dittomark: 0x3003,
+  divide: 0x00F7,
+  divides: 0x2223,
+  divisionslash: 0x2215,
+  djecyrillic: 0x0452,
+  dkshade: 0x2593,
+  dlinebelow: 0x1E0F,
+  dlsquare: 0x3397,
+  dmacron: 0x0111,
+  dmonospace: 0xFF44,
+  dnblock: 0x2584,
+  dochadathai: 0x0E0E,
+  dodekthai: 0x0E14,
+  dohiragana: 0x3069,
+  dokatakana: 0x30C9,
+  dollar: 0x0024,
+  dollarinferior: 0xF6E3,
+  dollarmonospace: 0xFF04,
+  dollaroldstyle: 0xF724,
+  dollarsmall: 0xFE69,
+  dollarsuperior: 0xF6E4,
+  dong: 0x20AB,
+  dorusquare: 0x3326,
+  dotaccent: 0x02D9,
+  dotaccentcmb: 0x0307,
+  dotbelowcmb: 0x0323,
+  dotbelowcomb: 0x0323,
+  dotkatakana: 0x30FB,
+  dotlessi: 0x0131,
+  dotlessj: 0xF6BE,
+  dotlessjstrokehook: 0x0284,
+  dotmath: 0x22C5,
+  dottedcircle: 0x25CC,
+  doubleyodpatah: 0xFB1F,
+  doubleyodpatahhebrew: 0xFB1F,
+  downtackbelowcmb: 0x031E,
+  downtackmod: 0x02D5,
+  dparen: 0x249F,
+  dsuperior: 0xF6EB,
+  dtail: 0x0256,
+  dtopbar: 0x018C,
+  duhiragana: 0x3065,
+  dukatakana: 0x30C5,
+  dz: 0x01F3,
+  dzaltone: 0x02A3,
+  dzcaron: 0x01C6,
+  dzcurl: 0x02A5,
+  dzeabkhasiancyrillic: 0x04E1,
+  dzecyrillic: 0x0455,
+  dzhecyrillic: 0x045F,
+  e: 0x0065,
+  eacute: 0x00E9,
+  earth: 0x2641,
+  ebengali: 0x098F,
+  ebopomofo: 0x311C,
+  ebreve: 0x0115,
+  ecandradeva: 0x090D,
+  ecandragujarati: 0x0A8D,
+  ecandravowelsigndeva: 0x0945,
+  ecandravowelsigngujarati: 0x0AC5,
+  ecaron: 0x011B,
+  ecedillabreve: 0x1E1D,
+  echarmenian: 0x0565,
+  echyiwnarmenian: 0x0587,
+  ecircle: 0x24D4,
+  ecircumflex: 0x00EA,
+  ecircumflexacute: 0x1EBF,
+  ecircumflexbelow: 0x1E19,
+  ecircumflexdotbelow: 0x1EC7,
+  ecircumflexgrave: 0x1EC1,
+  ecircumflexhookabove: 0x1EC3,
+  ecircumflextilde: 0x1EC5,
+  ecyrillic: 0x0454,
+  edblgrave: 0x0205,
+  edeva: 0x090F,
+  edieresis: 0x00EB,
+  edot: 0x0117,
+  edotaccent: 0x0117,
+  edotbelow: 0x1EB9,
+  eegurmukhi: 0x0A0F,
+  eematragurmukhi: 0x0A47,
+  efcyrillic: 0x0444,
+  egrave: 0x00E8,
+  egujarati: 0x0A8F,
+  eharmenian: 0x0567,
+  ehbopomofo: 0x311D,
+  ehiragana: 0x3048,
+  ehookabove: 0x1EBB,
+  eibopomofo: 0x311F,
+  eight: 0x0038,
+  eightarabic: 0x0668,
+  eightbengali: 0x09EE,
+  eightcircle: 0x2467,
+  eightcircleinversesansserif: 0x2791,
+  eightdeva: 0x096E,
+  eighteencircle: 0x2471,
+  eighteenparen: 0x2485,
+  eighteenperiod: 0x2499,
+  eightgujarati: 0x0AEE,
+  eightgurmukhi: 0x0A6E,
+  eighthackarabic: 0x0668,
+  eighthangzhou: 0x3028,
+  eighthnotebeamed: 0x266B,
+  eightideographicparen: 0x3227,
+  eightinferior: 0x2088,
+  eightmonospace: 0xFF18,
+  eightoldstyle: 0xF738,
+  eightparen: 0x247B,
+  eightperiod: 0x248F,
+  eightpersian: 0x06F8,
+  eightroman: 0x2177,
+  eightsuperior: 0x2078,
+  eightthai: 0x0E58,
+  einvertedbreve: 0x0207,
+  eiotifiedcyrillic: 0x0465,
+  ekatakana: 0x30A8,
+  ekatakanahalfwidth: 0xFF74,
+  ekonkargurmukhi: 0x0A74,
+  ekorean: 0x3154,
+  elcyrillic: 0x043B,
+  element: 0x2208,
+  elevencircle: 0x246A,
+  elevenparen: 0x247E,
+  elevenperiod: 0x2492,
+  elevenroman: 0x217A,
+  ellipsis: 0x2026,
+  ellipsisvertical: 0x22EE,
+  emacron: 0x0113,
+  emacronacute: 0x1E17,
+  emacrongrave: 0x1E15,
+  emcyrillic: 0x043C,
+  emdash: 0x2014,
+  emdashvertical: 0xFE31,
+  emonospace: 0xFF45,
+  emphasismarkarmenian: 0x055B,
+  emptyset: 0x2205,
+  enbopomofo: 0x3123,
+  encyrillic: 0x043D,
+  endash: 0x2013,
+  endashvertical: 0xFE32,
+  endescendercyrillic: 0x04A3,
+  eng: 0x014B,
+  engbopomofo: 0x3125,
+  enghecyrillic: 0x04A5,
+  enhookcyrillic: 0x04C8,
+  enspace: 0x2002,
+  eogonek: 0x0119,
+  eokorean: 0x3153,
+  eopen: 0x025B,
+  eopenclosed: 0x029A,
+  eopenreversed: 0x025C,
+  eopenreversedclosed: 0x025E,
+  eopenreversedhook: 0x025D,
+  eparen: 0x24A0,
+  epsilon: 0x03B5,
+  epsilontonos: 0x03AD,
+  equal: 0x003D,
+  equalmonospace: 0xFF1D,
+  equalsmall: 0xFE66,
+  equalsuperior: 0x207C,
+  equivalence: 0x2261,
+  erbopomofo: 0x3126,
+  ercyrillic: 0x0440,
+  ereversed: 0x0258,
+  ereversedcyrillic: 0x044D,
+  escyrillic: 0x0441,
+  esdescendercyrillic: 0x04AB,
+  esh: 0x0283,
+  eshcurl: 0x0286,
+  eshortdeva: 0x090E,
+  eshortvowelsigndeva: 0x0946,
+  eshreversedloop: 0x01AA,
+  eshsquatreversed: 0x0285,
+  esmallhiragana: 0x3047,
+  esmallkatakana: 0x30A7,
+  esmallkatakanahalfwidth: 0xFF6A,
+  estimated: 0x212E,
+  esuperior: 0xF6EC,
+  eta: 0x03B7,
+  etarmenian: 0x0568,
+  etatonos: 0x03AE,
+  eth: 0x00F0,
+  etilde: 0x1EBD,
+  etildebelow: 0x1E1B,
+  etnahtafoukhhebrew: 0x0591,
+  etnahtafoukhlefthebrew: 0x0591,
+  etnahtahebrew: 0x0591,
+  etnahtalefthebrew: 0x0591,
+  eturned: 0x01DD,
+  eukorean: 0x3161,
+  euro: 0x20AC,
+  evowelsignbengali: 0x09C7,
+  evowelsigndeva: 0x0947,
+  evowelsigngujarati: 0x0AC7,
+  exclam: 0x0021,
+  exclamarmenian: 0x055C,
+  exclamdbl: 0x203C,
+  exclamdown: 0x00A1,
+  exclamdownsmall: 0xF7A1,
+  exclammonospace: 0xFF01,
+  exclamsmall: 0xF721,
+  existential: 0x2203,
+  ezh: 0x0292,
+  ezhcaron: 0x01EF,
+  ezhcurl: 0x0293,
+  ezhreversed: 0x01B9,
+  ezhtail: 0x01BA,
+  f: 0x0066,
+  fadeva: 0x095E,
+  fagurmukhi: 0x0A5E,
+  fahrenheit: 0x2109,
+  fathaarabic: 0x064E,
+  fathalowarabic: 0x064E,
+  fathatanarabic: 0x064B,
+  fbopomofo: 0x3108,
+  fcircle: 0x24D5,
+  fdotaccent: 0x1E1F,
+  feharabic: 0x0641,
+  feharmenian: 0x0586,
+  fehfinalarabic: 0xFED2,
+  fehinitialarabic: 0xFED3,
+  fehmedialarabic: 0xFED4,
+  feicoptic: 0x03E5,
+  female: 0x2640,
+  ff: 0xFB00,
+  ffi: 0xFB03,
+  ffl: 0xFB04,
+  fi: 0xFB01,
+  fifteencircle: 0x246E,
+  fifteenparen: 0x2482,
+  fifteenperiod: 0x2496,
+  figuredash: 0x2012,
+  filledbox: 0x25A0,
+  filledrect: 0x25AC,
+  finalkaf: 0x05DA,
+  finalkafdagesh: 0xFB3A,
+  finalkafdageshhebrew: 0xFB3A,
+  finalkafhebrew: 0x05DA,
+  finalkafqamats: "05DA 05B8",
+  finalkafqamatshebrew: "05DA 05B8",
+  finalkafsheva: "05DA 05B0",
+  finalkafshevahebrew: "05DA 05B0",
+  finalmem: 0x05DD,
+  finalmemhebrew: 0x05DD,
+  finalnun: 0x05DF,
+  finalnunhebrew: 0x05DF,
+  finalpe: 0x05E3,
+  finalpehebrew: 0x05E3,
+  finaltsadi: 0x05E5,
+  finaltsadihebrew: 0x05E5,
+  firsttonechinese: 0x02C9,
+  fisheye: 0x25C9,
+  fitacyrillic: 0x0473,
+  five: 0x0035,
+  fivearabic: 0x0665,
+  fivebengali: 0x09EB,
+  fivecircle: 0x2464,
+  fivecircleinversesansserif: 0x278E,
+  fivedeva: 0x096B,
+  fiveeighths: 0x215D,
+  fivegujarati: 0x0AEB,
+  fivegurmukhi: 0x0A6B,
+  fivehackarabic: 0x0665,
+  fivehangzhou: 0x3025,
+  fiveideographicparen: 0x3224,
+  fiveinferior: 0x2085,
+  fivemonospace: 0xFF15,
+  fiveoldstyle: 0xF735,
+  fiveparen: 0x2478,
+  fiveperiod: 0x248C,
+  fivepersian: 0x06F5,
+  fiveroman: 0x2174,
+  fivesuperior: 0x2075,
+  fivethai: 0x0E55,
+  fl: 0xFB02,
+  florin: 0x0192,
+  fmonospace: 0xFF46,
+  fmsquare: 0x3399,
+  fofanthai: 0x0E1F,
+  fofathai: 0x0E1D,
+  fongmanthai: 0x0E4F,
+  forall: 0x2200,
+  four: 0x0034,
+  fourarabic: 0x0664,
+  fourbengali: 0x09EA,
+  fourcircle: 0x2463,
+  fourcircleinversesansserif: 0x278D,
+  fourdeva: 0x096A,
+  fourgujarati: 0x0AEA,
+  fourgurmukhi: 0x0A6A,
+  fourhackarabic: 0x0664,
+  fourhangzhou: 0x3024,
+  fourideographicparen: 0x3223,
+  fourinferior: 0x2084,
+  fourmonospace: 0xFF14,
+  fournumeratorbengali: 0x09F7,
+  fouroldstyle: 0xF734,
+  fourparen: 0x2477,
+  fourperiod: 0x248B,
+  fourpersian: 0x06F4,
+  fourroman: 0x2173,
+  foursuperior: 0x2074,
+  fourteencircle: 0x246D,
+  fourteenparen: 0x2481,
+  fourteenperiod: 0x2495,
+  fourthai: 0x0E54,
+  fourthtonechinese: 0x02CB,
+  fparen: 0x24A1,
+  fraction: 0x2044,
+  franc: 0x20A3,
+  g: 0x0067,
+  gabengali: 0x0997,
+  gacute: 0x01F5,
+  gadeva: 0x0917,
+  gafarabic: 0x06AF,
+  gaffinalarabic: 0xFB93,
+  gafinitialarabic: 0xFB94,
+  gafmedialarabic: 0xFB95,
+  gagujarati: 0x0A97,
+  gagurmukhi: 0x0A17,
+  gahiragana: 0x304C,
+  gakatakana: 0x30AC,
+  gamma: 0x03B3,
+  gammalatinsmall: 0x0263,
+  gammasuperior: 0x02E0,
+  gangiacoptic: 0x03EB,
+  gbopomofo: 0x310D,
+  gbreve: 0x011F,
+  gcaron: 0x01E7,
+  gcedilla: 0x0123,
+  gcircle: 0x24D6,
+  gcircumflex: 0x011D,
+  gcommaaccent: 0x0123,
+  gdot: 0x0121,
+  gdotaccent: 0x0121,
+  gecyrillic: 0x0433,
+  gehiragana: 0x3052,
+  gekatakana: 0x30B2,
+  geometricallyequal: 0x2251,
+  gereshaccenthebrew: 0x059C,
+  gereshhebrew: 0x05F3,
+  gereshmuqdamhebrew: 0x059D,
+  germandbls: 0x00DF,
+  gershayimaccenthebrew: 0x059E,
+  gershayimhebrew: 0x05F4,
+  getamark: 0x3013,
+  ghabengali: 0x0998,
+  ghadarmenian: 0x0572,
+  ghadeva: 0x0918,
+  ghagujarati: 0x0A98,
+  ghagurmukhi: 0x0A18,
+  ghainarabic: 0x063A,
+  ghainfinalarabic: 0xFECE,
+  ghaininitialarabic: 0xFECF,
+  ghainmedialarabic: 0xFED0,
+  ghemiddlehookcyrillic: 0x0495,
+  ghestrokecyrillic: 0x0493,
+  gheupturncyrillic: 0x0491,
+  ghhadeva: 0x095A,
+  ghhagurmukhi: 0x0A5A,
+  ghook: 0x0260,
+  ghzsquare: 0x3393,
+  gihiragana: 0x304E,
+  gikatakana: 0x30AE,
+  gimarmenian: 0x0563,
+  gimel: 0x05D2,
+  gimeldagesh: 0xFB32,
+  gimeldageshhebrew: 0xFB32,
+  gimelhebrew: 0x05D2,
+  gjecyrillic: 0x0453,
+  glottalinvertedstroke: 0x01BE,
+  glottalstop: 0x0294,
+  glottalstopinverted: 0x0296,
+  glottalstopmod: 0x02C0,
+  glottalstopreversed: 0x0295,
+  glottalstopreversedmod: 0x02C1,
+  glottalstopreversedsuperior: 0x02E4,
+  glottalstopstroke: 0x02A1,
+  glottalstopstrokereversed: 0x02A2,
+  gmacron: 0x1E21,
+  gmonospace: 0xFF47,
+  gohiragana: 0x3054,
+  gokatakana: 0x30B4,
+  gparen: 0x24A2,
+  gpasquare: 0x33AC,
+  gradient: 0x2207,
+  grave: 0x0060,
+  gravebelowcmb: 0x0316,
+  gravecmb: 0x0300,
+  gravecomb: 0x0300,
+  gravedeva: 0x0953,
+  gravelowmod: 0x02CE,
+  gravemonospace: 0xFF40,
+  gravetonecmb: 0x0340,
+  greater: 0x003E,
+  greaterequal: 0x2265,
+  greaterequalorless: 0x22DB,
+  greatermonospace: 0xFF1E,
+  greaterorequivalent: 0x2273,
+  greaterorless: 0x2277,
+  greateroverequal: 0x2267,
+  greatersmall: 0xFE65,
+  gscript: 0x0261,
+  gstroke: 0x01E5,
+  guhiragana: 0x3050,
+  guillemotleft: 0x00AB,
+  guillemotright: 0x00BB,
+  guilsinglleft: 0x2039,
+  guilsinglright: 0x203A,
+  gukatakana: 0x30B0,
+  guramusquare: 0x3318,
+  gysquare: 0x33C9,
+  h: 0x0068,
+  haabkhasiancyrillic: 0x04A9,
+  haaltonearabic: 0x06C1,
+  habengali: 0x09B9,
+  hadescendercyrillic: 0x04B3,
+  hadeva: 0x0939,
+  hagujarati: 0x0AB9,
+  hagurmukhi: 0x0A39,
+  haharabic: 0x062D,
+  hahfinalarabic: 0xFEA2,
+  hahinitialarabic: 0xFEA3,
+  hahiragana: 0x306F,
+  hahmedialarabic: 0xFEA4,
+  haitusquare: 0x332A,
+  hakatakana: 0x30CF,
+  hakatakanahalfwidth: 0xFF8A,
+  halantgurmukhi: 0x0A4D,
+  hamzaarabic: 0x0621,
+  hamzadammaarabic: "0621 064F",
+  hamzadammatanarabic: "0621 064C",
+  hamzafathaarabic: "0621 064E",
+  hamzafathatanarabic: "0621 064B",
+  hamzalowarabic: 0x0621,
+  hamzalowkasraarabic: "0621 0650",
+  hamzalowkasratanarabic: "0621 064D",
+  hamzasukunarabic: "0621 0652",
+  hangulfiller: 0x3164,
+  hardsigncyrillic: 0x044A,
+  harpoonleftbarbup: 0x21BC,
+  harpoonrightbarbup: 0x21C0,
+  hasquare: 0x33CA,
+  hatafpatah: 0x05B2,
+  hatafpatah16: 0x05B2,
+  hatafpatah23: 0x05B2,
+  hatafpatah2f: 0x05B2,
+  hatafpatahhebrew: 0x05B2,
+  hatafpatahnarrowhebrew: 0x05B2,
+  hatafpatahquarterhebrew: 0x05B2,
+  hatafpatahwidehebrew: 0x05B2,
+  hatafqamats: 0x05B3,
+  hatafqamats1b: 0x05B3,
+  hatafqamats28: 0x05B3,
+  hatafqamats34: 0x05B3,
+  hatafqamatshebrew: 0x05B3,
+  hatafqamatsnarrowhebrew: 0x05B3,
+  hatafqamatsquarterhebrew: 0x05B3,
+  hatafqamatswidehebrew: 0x05B3,
+  hatafsegol: 0x05B1,
+  hatafsegol17: 0x05B1,
+  hatafsegol24: 0x05B1,
+  hatafsegol30: 0x05B1,
+  hatafsegolhebrew: 0x05B1,
+  hatafsegolnarrowhebrew: 0x05B1,
+  hatafsegolquarterhebrew: 0x05B1,
+  hatafsegolwidehebrew: 0x05B1,
+  hbar: 0x0127,
+  hbopomofo: 0x310F,
+  hbrevebelow: 0x1E2B,
+  hcedilla: 0x1E29,
+  hcircle: 0x24D7,
+  hcircumflex: 0x0125,
+  hdieresis: 0x1E27,
+  hdotaccent: 0x1E23,
+  hdotbelow: 0x1E25,
+  he: 0x05D4,
+  heart: 0x2665,
+  heartsuitblack: 0x2665,
+  heartsuitwhite: 0x2661,
+  hedagesh: 0xFB34,
+  hedageshhebrew: 0xFB34,
+  hehaltonearabic: 0x06C1,
+  heharabic: 0x0647,
+  hehebrew: 0x05D4,
+  hehfinalaltonearabic: 0xFBA7,
+  hehfinalalttwoarabic: 0xFEEA,
+  hehfinalarabic: 0xFEEA,
+  hehhamzaabovefinalarabic: 0xFBA5,
+  hehhamzaaboveisolatedarabic: 0xFBA4,
+  hehinitialaltonearabic: 0xFBA8,
+  hehinitialarabic: 0xFEEB,
+  hehiragana: 0x3078,
+  hehmedialaltonearabic: 0xFBA9,
+  hehmedialarabic: 0xFEEC,
+  heiseierasquare: 0x337B,
+  hekatakana: 0x30D8,
+  hekatakanahalfwidth: 0xFF8D,
+  hekutaarusquare: 0x3336,
+  henghook: 0x0267,
+  herutusquare: 0x3339,
+  het: 0x05D7,
+  hethebrew: 0x05D7,
+  hhook: 0x0266,
+  hhooksuperior: 0x02B1,
+  hieuhacirclekorean: 0x327B,
+  hieuhaparenkorean: 0x321B,
+  hieuhcirclekorean: 0x326D,
+  hieuhkorean: 0x314E,
+  hieuhparenkorean: 0x320D,
+  hihiragana: 0x3072,
+  hikatakana: 0x30D2,
+  hikatakanahalfwidth: 0xFF8B,
+  hiriq: 0x05B4,
+  hiriq14: 0x05B4,
+  hiriq21: 0x05B4,
+  hiriq2d: 0x05B4,
+  hiriqhebrew: 0x05B4,
+  hiriqnarrowhebrew: 0x05B4,
+  hiriqquarterhebrew: 0x05B4,
+  hiriqwidehebrew: 0x05B4,
+  hlinebelow: 0x1E96,
+  hmonospace: 0xFF48,
+  hoarmenian: 0x0570,
+  hohipthai: 0x0E2B,
+  hohiragana: 0x307B,
+  hokatakana: 0x30DB,
+  hokatakanahalfwidth: 0xFF8E,
+  holam: 0x05B9,
+  holam19: 0x05B9,
+  holam26: 0x05B9,
+  holam32: 0x05B9,
+  holamhebrew: 0x05B9,
+  holamnarrowhebrew: 0x05B9,
+  holamquarterhebrew: 0x05B9,
+  holamwidehebrew: 0x05B9,
+  honokhukthai: 0x0E2E,
+  hookabovecomb: 0x0309,
+  hookcmb: 0x0309,
+  hookpalatalizedbelowcmb: 0x0321,
+  hookretroflexbelowcmb: 0x0322,
+  hoonsquare: 0x3342,
+  horicoptic: 0x03E9,
+  horizontalbar: 0x2015,
+  horncmb: 0x031B,
+  hotsprings: 0x2668,
+  house: 0x2302,
+  hparen: 0x24A3,
+  hsuperior: 0x02B0,
+  hturned: 0x0265,
+  huhiragana: 0x3075,
+  huiitosquare: 0x3333,
+  hukatakana: 0x30D5,
+  hukatakanahalfwidth: 0xFF8C,
+  hungarumlaut: 0x02DD,
+  hungarumlautcmb: 0x030B,
+  hv: 0x0195,
+  hyphen: 0x002D,
+  hypheninferior: 0xF6E5,
+  hyphenmonospace: 0xFF0D,
+  hyphensmall: 0xFE63,
+  hyphensuperior: 0xF6E6,
+  hyphentwo: 0x2010,
+  i: 0x0069,
+  iacute: 0x00ED,
+  iacyrillic: 0x044F,
+  ibengali: 0x0987,
+  ibopomofo: 0x3127,
+  ibreve: 0x012D,
+  icaron: 0x01D0,
+  icircle: 0x24D8,
+  icircumflex: 0x00EE,
+  icyrillic: 0x0456,
+  idblgrave: 0x0209,
+  ideographearthcircle: 0x328F,
+  ideographfirecircle: 0x328B,
+  ideographicallianceparen: 0x323F,
+  ideographiccallparen: 0x323A,
+  ideographiccentrecircle: 0x32A5,
+  ideographicclose: 0x3006,
+  ideographiccomma: 0x3001,
+  ideographiccommaleft: 0xFF64,
+  ideographiccongratulationparen: 0x3237,
+  ideographiccorrectcircle: 0x32A3,
+  ideographicearthparen: 0x322F,
+  ideographicenterpriseparen: 0x323D,
+  ideographicexcellentcircle: 0x329D,
+  ideographicfestivalparen: 0x3240,
+  ideographicfinancialcircle: 0x3296,
+  ideographicfinancialparen: 0x3236,
+  ideographicfireparen: 0x322B,
+  ideographichaveparen: 0x3232,
+  ideographichighcircle: 0x32A4,
+  ideographiciterationmark: 0x3005,
+  ideographiclaborcircle: 0x3298,
+  ideographiclaborparen: 0x3238,
+  ideographicleftcircle: 0x32A7,
+  ideographiclowcircle: 0x32A6,
+  ideographicmedicinecircle: 0x32A9,
+  ideographicmetalparen: 0x322E,
+  ideographicmoonparen: 0x322A,
+  ideographicnameparen: 0x3234,
+  ideographicperiod: 0x3002,
+  ideographicprintcircle: 0x329E,
+  ideographicreachparen: 0x3243,
+  ideographicrepresentparen: 0x3239,
+  ideographicresourceparen: 0x323E,
+  ideographicrightcircle: 0x32A8,
+  ideographicsecretcircle: 0x3299,
+  ideographicselfparen: 0x3242,
+  ideographicsocietyparen: 0x3233,
+  ideographicspace: 0x3000,
+  ideographicspecialparen: 0x3235,
+  ideographicstockparen: 0x3231,
+  ideographicstudyparen: 0x323B,
+  ideographicsunparen: 0x3230,
+  ideographicsuperviseparen: 0x323C,
+  ideographicwaterparen: 0x322C,
+  ideographicwoodparen: 0x322D,
+  ideographiczero: 0x3007,
+  ideographmetalcircle: 0x328E,
+  ideographmooncircle: 0x328A,
+  ideographnamecircle: 0x3294,
+  ideographsuncircle: 0x3290,
+  ideographwatercircle: 0x328C,
+  ideographwoodcircle: 0x328D,
+  ideva: 0x0907,
+  idieresis: 0x00EF,
+  idieresisacute: 0x1E2F,
+  idieresiscyrillic: 0x04E5,
+  idotbelow: 0x1ECB,
+  iebrevecyrillic: 0x04D7,
+  iecyrillic: 0x0435,
+  ieungacirclekorean: 0x3275,
+  ieungaparenkorean: 0x3215,
+  ieungcirclekorean: 0x3267,
+  ieungkorean: 0x3147,
+  ieungparenkorean: 0x3207,
+  igrave: 0x00EC,
+  igujarati: 0x0A87,
+  igurmukhi: 0x0A07,
+  ihiragana: 0x3044,
+  ihookabove: 0x1EC9,
+  iibengali: 0x0988,
+  iicyrillic: 0x0438,
+  iideva: 0x0908,
+  iigujarati: 0x0A88,
+  iigurmukhi: 0x0A08,
+  iimatragurmukhi: 0x0A40,
+  iinvertedbreve: 0x020B,
+  iishortcyrillic: 0x0439,
+  iivowelsignbengali: 0x09C0,
+  iivowelsigndeva: 0x0940,
+  iivowelsigngujarati: 0x0AC0,
+  ij: 0x0133,
+  ikatakana: 0x30A4,
+  ikatakanahalfwidth: 0xFF72,
+  ikorean: 0x3163,
+  ilde: 0x02DC,
+  iluyhebrew: 0x05AC,
+  imacron: 0x012B,
+  imacroncyrillic: 0x04E3,
+  imageorapproximatelyequal: 0x2253,
+  imatragurmukhi: 0x0A3F,
+  imonospace: 0xFF49,
+  increment: 0x2206,
+  infinity: 0x221E,
+  iniarmenian: 0x056B,
+  integral: 0x222B,
+  integralbottom: 0x2321,
+  integralbt: 0x2321,
+  integralex: 0xF8F5,
+  integraltop: 0x2320,
+  integraltp: 0x2320,
+  intersection: 0x2229,
+  intisquare: 0x3305,
+  invbullet: 0x25D8,
+  invcircle: 0x25D9,
+  invsmileface: 0x263B,
+  iocyrillic: 0x0451,
+  iogonek: 0x012F,
+  iota: 0x03B9,
+  iotadieresis: 0x03CA,
+  iotadieresistonos: 0x0390,
+  iotalatin: 0x0269,
+  iotatonos: 0x03AF,
+  iparen: 0x24A4,
+  irigurmukhi: 0x0A72,
+  ismallhiragana: 0x3043,
+  ismallkatakana: 0x30A3,
+  ismallkatakanahalfwidth: 0xFF68,
+  issharbengali: 0x09FA,
+  istroke: 0x0268,
+  isuperior: 0xF6ED,
+  iterationhiragana: 0x309D,
+  iterationkatakana: 0x30FD,
+  itilde: 0x0129,
+  itildebelow: 0x1E2D,
+  iubopomofo: 0x3129,
+  iucyrillic: 0x044E,
+  ivowelsignbengali: 0x09BF,
+  ivowelsigndeva: 0x093F,
+  ivowelsigngujarati: 0x0ABF,
+  izhitsacyrillic: 0x0475,
+  izhitsadblgravecyrillic: 0x0477,
+  j: 0x006A,
+  jaarmenian: 0x0571,
+  jabengali: 0x099C,
+  jadeva: 0x091C,
+  jagujarati: 0x0A9C,
+  jagurmukhi: 0x0A1C,
+  jbopomofo: 0x3110,
+  jcaron: 0x01F0,
+  jcircle: 0x24D9,
+  jcircumflex: 0x0135,
+  jcrossedtail: 0x029D,
+  jdotlessstroke: 0x025F,
+  jecyrillic: 0x0458,
+  jeemarabic: 0x062C,
+  jeemfinalarabic: 0xFE9E,
+  jeeminitialarabic: 0xFE9F,
+  jeemmedialarabic: 0xFEA0,
+  jeharabic: 0x0698,
+  jehfinalarabic: 0xFB8B,
+  jhabengali: 0x099D,
+  jhadeva: 0x091D,
+  jhagujarati: 0x0A9D,
+  jhagurmukhi: 0x0A1D,
+  jheharmenian: 0x057B,
+  jis: 0x3004,
+  jmonospace: 0xFF4A,
+  jparen: 0x24A5,
+  jsuperior: 0x02B2,
+  k: 0x006B,
+  kabashkircyrillic: 0x04A1,
+  kabengali: 0x0995,
+  kacute: 0x1E31,
+  kacyrillic: 0x043A,
+  kadescendercyrillic: 0x049B,
+  kadeva: 0x0915,
+  kaf: 0x05DB,
+  kafarabic: 0x0643,
+  kafdagesh: 0xFB3B,
+  kafdageshhebrew: 0xFB3B,
+  kaffinalarabic: 0xFEDA,
+  kafhebrew: 0x05DB,
+  kafinitialarabic: 0xFEDB,
+  kafmedialarabic: 0xFEDC,
+  kafrafehebrew: 0xFB4D,
+  kagujarati: 0x0A95,
+  kagurmukhi: 0x0A15,
+  kahiragana: 0x304B,
+  kahookcyrillic: 0x04C4,
+  kakatakana: 0x30AB,
+  kakatakanahalfwidth: 0xFF76,
+  kappa: 0x03BA,
+  kappasymbolgreek: 0x03F0,
+  kapyeounmieumkorean: 0x3171,
+  kapyeounphieuphkorean: 0x3184,
+  kapyeounpieupkorean: 0x3178,
+  kapyeounssangpieupkorean: 0x3179,
+  karoriisquare: 0x330D,
+  kashidaautoarabic: 0x0640,
+  kashidaautonosidebearingarabic: 0x0640,
+  kasmallkatakana: 0x30F5,
+  kasquare: 0x3384,
+  kasraarabic: 0x0650,
+  kasratanarabic: 0x064D,
+  kastrokecyrillic: 0x049F,
+  katahiraprolongmarkhalfwidth: 0xFF70,
+  kaverticalstrokecyrillic: 0x049D,
+  kbopomofo: 0x310E,
+  kcalsquare: 0x3389,
+  kcaron: 0x01E9,
+  kcedilla: 0x0137,
+  kcircle: 0x24DA,
+  kcommaaccent: 0x0137,
+  kdotbelow: 0x1E33,
+  keharmenian: 0x0584,
+  kehiragana: 0x3051,
+  kekatakana: 0x30B1,
+  kekatakanahalfwidth: 0xFF79,
+  kenarmenian: 0x056F,
+  kesmallkatakana: 0x30F6,
+  kgreenlandic: 0x0138,
+  khabengali: 0x0996,
+  khacyrillic: 0x0445,
+  khadeva: 0x0916,
+  khagujarati: 0x0A96,
+  khagurmukhi: 0x0A16,
+  khaharabic: 0x062E,
+  khahfinalarabic: 0xFEA6,
+  khahinitialarabic: 0xFEA7,
+  khahmedialarabic: 0xFEA8,
+  kheicoptic: 0x03E7,
+  khhadeva: 0x0959,
+  khhagurmukhi: 0x0A59,
+  khieukhacirclekorean: 0x3278,
+  khieukhaparenkorean: 0x3218,
+  khieukhcirclekorean: 0x326A,
+  khieukhkorean: 0x314B,
+  khieukhparenkorean: 0x320A,
+  khokhaithai: 0x0E02,
+  khokhonthai: 0x0E05,
+  khokhuatthai: 0x0E03,
+  khokhwaithai: 0x0E04,
+  khomutthai: 0x0E5B,
+  khook: 0x0199,
+  khorakhangthai: 0x0E06,
+  khzsquare: 0x3391,
+  kihiragana: 0x304D,
+  kikatakana: 0x30AD,
+  kikatakanahalfwidth: 0xFF77,
+  kiroguramusquare: 0x3315,
+  kiromeetorusquare: 0x3316,
+  kirosquare: 0x3314,
+  kiyeokacirclekorean: 0x326E,
+  kiyeokaparenkorean: 0x320E,
+  kiyeokcirclekorean: 0x3260,
+  kiyeokkorean: 0x3131,
+  kiyeokparenkorean: 0x3200,
+  kiyeoksioskorean: 0x3133,
+  kjecyrillic: 0x045C,
+  klinebelow: 0x1E35,
+  klsquare: 0x3398,
+  kmcubedsquare: 0x33A6,
+  kmonospace: 0xFF4B,
+  kmsquaredsquare: 0x33A2,
+  kohiragana: 0x3053,
+  kohmsquare: 0x33C0,
+  kokaithai: 0x0E01,
+  kokatakana: 0x30B3,
+  kokatakanahalfwidth: 0xFF7A,
+  kooposquare: 0x331E,
+  koppacyrillic: 0x0481,
+  koreanstandardsymbol: 0x327F,
+  koroniscmb: 0x0343,
+  kparen: 0x24A6,
+  kpasquare: 0x33AA,
+  ksicyrillic: 0x046F,
+  ktsquare: 0x33CF,
+  kturned: 0x029E,
+  kuhiragana: 0x304F,
+  kukatakana: 0x30AF,
+  kukatakanahalfwidth: 0xFF78,
+  kvsquare: 0x33B8,
+  kwsquare: 0x33BE,
+  l: 0x006C,
+  labengali: 0x09B2,
+  lacute: 0x013A,
+  ladeva: 0x0932,
+  lagujarati: 0x0AB2,
+  lagurmukhi: 0x0A32,
+  lakkhangyaothai: 0x0E45,
+  lamaleffinalarabic: 0xFEFC,
+  lamalefhamzaabovefinalarabic: 0xFEF8,
+  lamalefhamzaaboveisolatedarabic: 0xFEF7,
+  lamalefhamzabelowfinalarabic: 0xFEFA,
+  lamalefhamzabelowisolatedarabic: 0xFEF9,
+  lamalefisolatedarabic: 0xFEFB,
+  lamalefmaddaabovefinalarabic: 0xFEF6,
+  lamalefmaddaaboveisolatedarabic: 0xFEF5,
+  lamarabic: 0x0644,
+  lambda: 0x03BB,
+  lambdastroke: 0x019B,
+  lamed: 0x05DC,
+  lameddagesh: 0xFB3C,
+  lameddageshhebrew: 0xFB3C,
+  lamedhebrew: 0x05DC,
+  lamedholam: "05DC 05B9",
+  lamedholamdagesh: "05DC 05B9 05BC",
+  lamedholamdageshhebrew: "05DC 05B9 05BC",
+  lamedholamhebrew: "05DC 05B9",
+  lamfinalarabic: 0xFEDE,
+  lamhahinitialarabic: 0xFCCA,
+  laminitialarabic: 0xFEDF,
+  lamjeeminitialarabic: 0xFCC9,
+  lamkhahinitialarabic: 0xFCCB,
+  lamlamhehisolatedarabic: 0xFDF2,
+  lammedialarabic: 0xFEE0,
+  lammeemhahinitialarabic: 0xFD88,
+  lammeeminitialarabic: 0xFCCC,
+  lammeemjeeminitialarabic: "FEDF FEE4 FEA0",
+  lammeemkhahinitialarabic: "FEDF FEE4 FEA8",
+  largecircle: 0x25EF,
+  lbar: 0x019A,
+  lbelt: 0x026C,
+  lbopomofo: 0x310C,
+  lcaron: 0x013E,
+  lcedilla: 0x013C,
+  lcircle: 0x24DB,
+  lcircumflexbelow: 0x1E3D,
+  lcommaaccent: 0x013C,
+  ldot: 0x0140,
+  ldotaccent: 0x0140,
+  ldotbelow: 0x1E37,
+  ldotbelowmacron: 0x1E39,
+  leftangleabovecmb: 0x031A,
+  lefttackbelowcmb: 0x0318,
+  less: 0x003C,
+  lessequal: 0x2264,
+  lessequalorgreater: 0x22DA,
+  lessmonospace: 0xFF1C,
+  lessorequivalent: 0x2272,
+  lessorgreater: 0x2276,
+  lessoverequal: 0x2266,
+  lesssmall: 0xFE64,
+  lezh: 0x026E,
+  lfblock: 0x258C,
+  lhookretroflex: 0x026D,
+  lira: 0x20A4,
+  liwnarmenian: 0x056C,
+  lj: 0x01C9,
+  ljecyrillic: 0x0459,
+  ll: 0xF6C0,
+  lladeva: 0x0933,
+  llagujarati: 0x0AB3,
+  llinebelow: 0x1E3B,
+  llladeva: 0x0934,
+  llvocalicbengali: 0x09E1,
+  llvocalicdeva: 0x0961,
+  llvocalicvowelsignbengali: 0x09E3,
+  llvocalicvowelsigndeva: 0x0963,
+  lmiddletilde: 0x026B,
+  lmonospace: 0xFF4C,
+  lmsquare: 0x33D0,
+  lochulathai: 0x0E2C,
+  logicaland: 0x2227,
+  logicalnot: 0x00AC,
+  logicalnotreversed: 0x2310,
+  logicalor: 0x2228,
+  lolingthai: 0x0E25,
+  longs: 0x017F,
+  lowlinecenterline: 0xFE4E,
+  lowlinecmb: 0x0332,
+  lowlinedashed: 0xFE4D,
+  lozenge: 0x25CA,
+  lparen: 0x24A7,
+  lslash: 0x0142,
+  lsquare: 0x2113,
+  lsuperior: 0xF6EE,
+  ltshade: 0x2591,
+  luthai: 0x0E26,
+  lvocalicbengali: 0x098C,
+  lvocalicdeva: 0x090C,
+  lvocalicvowelsignbengali: 0x09E2,
+  lvocalicvowelsigndeva: 0x0962,
+  lxsquare: 0x33D3,
+  m: 0x006D,
+  mabengali: 0x09AE,
+  macron: 0x00AF,
+  macronbelowcmb: 0x0331,
+  macroncmb: 0x0304,
+  macronlowmod: 0x02CD,
+  macronmonospace: 0xFFE3,
+  macute: 0x1E3F,
+  madeva: 0x092E,
+  magujarati: 0x0AAE,
+  magurmukhi: 0x0A2E,
+  mahapakhhebrew: 0x05A4,
+  mahapakhlefthebrew: 0x05A4,
+  mahiragana: 0x307E,
+  maichattawalowleftthai: 0xF895,
+  maichattawalowrightthai: 0xF894,
+  maichattawathai: 0x0E4B,
+  maichattawaupperleftthai: 0xF893,
+  maieklowleftthai: 0xF88C,
+  maieklowrightthai: 0xF88B,
+  maiekthai: 0x0E48,
+  maiekupperleftthai: 0xF88A,
+  maihanakatleftthai: 0xF884,
+  maihanakatthai: 0x0E31,
+  maitaikhuleftthai: 0xF889,
+  maitaikhuthai: 0x0E47,
+  maitholowleftthai: 0xF88F,
+  maitholowrightthai: 0xF88E,
+  maithothai: 0x0E49,
+  maithoupperleftthai: 0xF88D,
+  maitrilowleftthai: 0xF892,
+  maitrilowrightthai: 0xF891,
+  maitrithai: 0x0E4A,
+  maitriupperleftthai: 0xF890,
+  maiyamokthai: 0x0E46,
+  makatakana: 0x30DE,
+  makatakanahalfwidth: 0xFF8F,
+  male: 0x2642,
+  mansyonsquare: 0x3347,
+  maqafhebrew: 0x05BE,
+  mars: 0x2642,
+  masoracirclehebrew: 0x05AF,
+  masquare: 0x3383,
+  mbopomofo: 0x3107,
+  mbsquare: 0x33D4,
+  mcircle: 0x24DC,
+  mcubedsquare: 0x33A5,
+  mdotaccent: 0x1E41,
+  mdotbelow: 0x1E43,
+  meemarabic: 0x0645,
+  meemfinalarabic: 0xFEE2,
+  meeminitialarabic: 0xFEE3,
+  meemmedialarabic: 0xFEE4,
+  meemmeeminitialarabic: 0xFCD1,
+  meemmeemisolatedarabic: 0xFC48,
+  meetorusquare: 0x334D,
+  mehiragana: 0x3081,
+  meizierasquare: 0x337E,
+  mekatakana: 0x30E1,
+  mekatakanahalfwidth: 0xFF92,
+  mem: 0x05DE,
+  memdagesh: 0xFB3E,
+  memdageshhebrew: 0xFB3E,
+  memhebrew: 0x05DE,
+  menarmenian: 0x0574,
+  merkhahebrew: 0x05A5,
+  merkhakefulahebrew: 0x05A6,
+  merkhakefulalefthebrew: 0x05A6,
+  merkhalefthebrew: 0x05A5,
+  mhook: 0x0271,
+  mhzsquare: 0x3392,
+  middledotkatakanahalfwidth: 0xFF65,
+  middot: 0x00B7,
+  mieumacirclekorean: 0x3272,
+  mieumaparenkorean: 0x3212,
+  mieumcirclekorean: 0x3264,
+  mieumkorean: 0x3141,
+  mieumpansioskorean: 0x3170,
+  mieumparenkorean: 0x3204,
+  mieumpieupkorean: 0x316E,
+  mieumsioskorean: 0x316F,
+  mihiragana: 0x307F,
+  mikatakana: 0x30DF,
+  mikatakanahalfwidth: 0xFF90,
+  minus: 0x2212,
+  minusbelowcmb: 0x0320,
+  minuscircle: 0x2296,
+  minusmod: 0x02D7,
+  minusplus: 0x2213,
+  minute: 0x2032,
+  miribaarusquare: 0x334A,
+  mirisquare: 0x3349,
+  mlonglegturned: 0x0270,
+  mlsquare: 0x3396,
+  mmcubedsquare: 0x33A3,
+  mmonospace: 0xFF4D,
+  mmsquaredsquare: 0x339F,
+  mohiragana: 0x3082,
+  mohmsquare: 0x33C1,
+  mokatakana: 0x30E2,
+  mokatakanahalfwidth: 0xFF93,
+  molsquare: 0x33D6,
+  momathai: 0x0E21,
+  moverssquare: 0x33A7,
+  moverssquaredsquare: 0x33A8,
+  mparen: 0x24A8,
+  mpasquare: 0x33AB,
+  mssquare: 0x33B3,
+  msuperior: 0xF6EF,
+  mturned: 0x026F,
+  mu: 0x00B5,
+  mu1: 0x00B5,
+  muasquare: 0x3382,
+  muchgreater: 0x226B,
+  muchless: 0x226A,
+  mufsquare: 0x338C,
+  mugreek: 0x03BC,
+  mugsquare: 0x338D,
+  muhiragana: 0x3080,
+  mukatakana: 0x30E0,
+  mukatakanahalfwidth: 0xFF91,
+  mulsquare: 0x3395,
+  multiply: 0x00D7,
+  mumsquare: 0x339B,
+  munahhebrew: 0x05A3,
+  munahlefthebrew: 0x05A3,
+  musicalnote: 0x266A,
+  musicalnotedbl: 0x266B,
+  musicflatsign: 0x266D,
+  musicsharpsign: 0x266F,
+  mussquare: 0x33B2,
+  muvsquare: 0x33B6,
+  muwsquare: 0x33BC,
+  mvmegasquare: 0x33B9,
+  mvsquare: 0x33B7,
+  mwmegasquare: 0x33BF,
+  mwsquare: 0x33BD,
+  n: 0x006E,
+  nabengali: 0x09A8,
+  nabla: 0x2207,
+  nacute: 0x0144,
+  nadeva: 0x0928,
+  nagujarati: 0x0AA8,
+  nagurmukhi: 0x0A28,
+  nahiragana: 0x306A,
+  nakatakana: 0x30CA,
+  nakatakanahalfwidth: 0xFF85,
+  napostrophe: 0x0149,
+  nasquare: 0x3381,
+  nbopomofo: 0x310B,
+  nbspace: 0x00A0,
+  ncaron: 0x0148,
+  ncedilla: 0x0146,
+  ncircle: 0x24DD,
+  ncircumflexbelow: 0x1E4B,
+  ncommaaccent: 0x0146,
+  ndotaccent: 0x1E45,
+  ndotbelow: 0x1E47,
+  nehiragana: 0x306D,
+  nekatakana: 0x30CD,
+  nekatakanahalfwidth: 0xFF88,
+  newsheqelsign: 0x20AA,
+  nfsquare: 0x338B,
+  ngabengali: 0x0999,
+  ngadeva: 0x0919,
+  ngagujarati: 0x0A99,
+  ngagurmukhi: 0x0A19,
+  ngonguthai: 0x0E07,
+  nhiragana: 0x3093,
+  nhookleft: 0x0272,
+  nhookretroflex: 0x0273,
+  nieunacirclekorean: 0x326F,
+  nieunaparenkorean: 0x320F,
+  nieuncieuckorean: 0x3135,
+  nieuncirclekorean: 0x3261,
+  nieunhieuhkorean: 0x3136,
+  nieunkorean: 0x3134,
+  nieunpansioskorean: 0x3168,
+  nieunparenkorean: 0x3201,
+  nieunsioskorean: 0x3167,
+  nieuntikeutkorean: 0x3166,
+  nihiragana: 0x306B,
+  nikatakana: 0x30CB,
+  nikatakanahalfwidth: 0xFF86,
+  nikhahitleftthai: 0xF899,
+  nikhahitthai: 0x0E4D,
+  nine: 0x0039,
+  ninearabic: 0x0669,
+  ninebengali: 0x09EF,
+  ninecircle: 0x2468,
+  ninecircleinversesansserif: 0x2792,
+  ninedeva: 0x096F,
+  ninegujarati: 0x0AEF,
+  ninegurmukhi: 0x0A6F,
+  ninehackarabic: 0x0669,
+  ninehangzhou: 0x3029,
+  nineideographicparen: 0x3228,
+  nineinferior: 0x2089,
+  ninemonospace: 0xFF19,
+  nineoldstyle: 0xF739,
+  nineparen: 0x247C,
+  nineperiod: 0x2490,
+  ninepersian: 0x06F9,
+  nineroman: 0x2178,
+  ninesuperior: 0x2079,
+  nineteencircle: 0x2472,
+  nineteenparen: 0x2486,
+  nineteenperiod: 0x249A,
+  ninethai: 0x0E59,
+  nj: 0x01CC,
+  njecyrillic: 0x045A,
+  nkatakana: 0x30F3,
+  nkatakanahalfwidth: 0xFF9D,
+  nlegrightlong: 0x019E,
+  nlinebelow: 0x1E49,
+  nmonospace: 0xFF4E,
+  nmsquare: 0x339A,
+  nnabengali: 0x09A3,
+  nnadeva: 0x0923,
+  nnagujarati: 0x0AA3,
+  nnagurmukhi: 0x0A23,
+  nnnadeva: 0x0929,
+  nohiragana: 0x306E,
+  nokatakana: 0x30CE,
+  nokatakanahalfwidth: 0xFF89,
+  nonbreakingspace: 0x00A0,
+  nonenthai: 0x0E13,
+  nonuthai: 0x0E19,
+  noonarabic: 0x0646,
+  noonfinalarabic: 0xFEE6,
+  noonghunnaarabic: 0x06BA,
+  noonghunnafinalarabic: 0xFB9F,
+  noonhehinitialarabic: "FEE7 FEEC",
+  nooninitialarabic: 0xFEE7,
+  noonjeeminitialarabic: 0xFCD2,
+  noonjeemisolatedarabic: 0xFC4B,
+  noonmedialarabic: 0xFEE8,
+  noonmeeminitialarabic: 0xFCD5,
+  noonmeemisolatedarabic: 0xFC4E,
+  noonnoonfinalarabic: 0xFC8D,
+  notcontains: 0x220C,
+  notelement: 0x2209,
+  notelementof: 0x2209,
+  notequal: 0x2260,
+  notgreater: 0x226F,
+  notgreaternorequal: 0x2271,
+  notgreaternorless: 0x2279,
+  notidentical: 0x2262,
+  notless: 0x226E,
+  notlessnorequal: 0x2270,
+  notparallel: 0x2226,
+  notprecedes: 0x2280,
+  notsubset: 0x2284,
+  notsucceeds: 0x2281,
+  notsuperset: 0x2285,
+  nowarmenian: 0x0576,
+  nparen: 0x24A9,
+  nssquare: 0x33B1,
+  nsuperior: 0x207F,
+  ntilde: 0x00F1,
+  nu: 0x03BD,
+  nuhiragana: 0x306C,
+  nukatakana: 0x30CC,
+  nukatakanahalfwidth: 0xFF87,
+  nuktabengali: 0x09BC,
+  nuktadeva: 0x093C,
+  nuktagujarati: 0x0ABC,
+  nuktagurmukhi: 0x0A3C,
+  numbersign: 0x0023,
+  numbersignmonospace: 0xFF03,
+  numbersignsmall: 0xFE5F,
+  numeralsigngreek: 0x0374,
+  numeralsignlowergreek: 0x0375,
+  numero: 0x2116,
+  nun: 0x05E0,
+  nundagesh: 0xFB40,
+  nundageshhebrew: 0xFB40,
+  nunhebrew: 0x05E0,
+  nvsquare: 0x33B5,
+  nwsquare: 0x33BB,
+  nyabengali: 0x099E,
+  nyadeva: 0x091E,
+  nyagujarati: 0x0A9E,
+  nyagurmukhi: 0x0A1E,
+  o: 0x006F,
+  oacute: 0x00F3,
+  oangthai: 0x0E2D,
+  obarred: 0x0275,
+  obarredcyrillic: 0x04E9,
+  obarreddieresiscyrillic: 0x04EB,
+  obengali: 0x0993,
+  obopomofo: 0x311B,
+  obreve: 0x014F,
+  ocandradeva: 0x0911,
+  ocandragujarati: 0x0A91,
+  ocandravowelsigndeva: 0x0949,
+  ocandravowelsigngujarati: 0x0AC9,
+  ocaron: 0x01D2,
+  ocircle: 0x24DE,
+  ocircumflex: 0x00F4,
+  ocircumflexacute: 0x1ED1,
+  ocircumflexdotbelow: 0x1ED9,
+  ocircumflexgrave: 0x1ED3,
+  ocircumflexhookabove: 0x1ED5,
+  ocircumflextilde: 0x1ED7,
+  ocyrillic: 0x043E,
+  odblacute: 0x0151,
+  odblgrave: 0x020D,
+  odeva: 0x0913,
+  odieresis: 0x00F6,
+  odieresiscyrillic: 0x04E7,
+  odotbelow: 0x1ECD,
+  oe: 0x0153,
+  oekorean: 0x315A,
+  ogonek: 0x02DB,
+  ogonekcmb: 0x0328,
+  ograve: 0x00F2,
+  ogujarati: 0x0A93,
+  oharmenian: 0x0585,
+  ohiragana: 0x304A,
+  ohookabove: 0x1ECF,
+  ohorn: 0x01A1,
+  ohornacute: 0x1EDB,
+  ohorndotbelow: 0x1EE3,
+  ohorngrave: 0x1EDD,
+  ohornhookabove: 0x1EDF,
+  ohorntilde: 0x1EE1,
+  ohungarumlaut: 0x0151,
+  oi: 0x01A3,
+  oinvertedbreve: 0x020F,
+  okatakana: 0x30AA,
+  okatakanahalfwidth: 0xFF75,
+  okorean: 0x3157,
+  olehebrew: 0x05AB,
+  omacron: 0x014D,
+  omacronacute: 0x1E53,
+  omacrongrave: 0x1E51,
+  omdeva: 0x0950,
+  omega: 0x03C9,
+  omega1: 0x03D6,
+  omegacyrillic: 0x0461,
+  omegalatinclosed: 0x0277,
+  omegaroundcyrillic: 0x047B,
+  omegatitlocyrillic: 0x047D,
+  omegatonos: 0x03CE,
+  omgujarati: 0x0AD0,
+  omicron: 0x03BF,
+  omicrontonos: 0x03CC,
+  omonospace: 0xFF4F,
+  one: 0x0031,
+  onearabic: 0x0661,
+  onebengali: 0x09E7,
+  onecircle: 0x2460,
+  onecircleinversesansserif: 0x278A,
+  onedeva: 0x0967,
+  onedotenleader: 0x2024,
+  oneeighth: 0x215B,
+  onefitted: 0xF6DC,
+  onegujarati: 0x0AE7,
+  onegurmukhi: 0x0A67,
+  onehackarabic: 0x0661,
+  onehalf: 0x00BD,
+  onehangzhou: 0x3021,
+  oneideographicparen: 0x3220,
+  oneinferior: 0x2081,
+  onemonospace: 0xFF11,
+  onenumeratorbengali: 0x09F4,
+  oneoldstyle: 0xF731,
+  oneparen: 0x2474,
+  oneperiod: 0x2488,
+  onepersian: 0x06F1,
+  onequarter: 0x00BC,
+  oneroman: 0x2170,
+  onesuperior: 0x00B9,
+  onethai: 0x0E51,
+  onethird: 0x2153,
+  oogonek: 0x01EB,
+  oogonekmacron: 0x01ED,
+  oogurmukhi: 0x0A13,
+  oomatragurmukhi: 0x0A4B,
+  oopen: 0x0254,
+  oparen: 0x24AA,
+  openbullet: 0x25E6,
+  option: 0x2325,
+  ordfeminine: 0x00AA,
+  ordmasculine: 0x00BA,
+  orthogonal: 0x221F,
+  oshortdeva: 0x0912,
+  oshortvowelsigndeva: 0x094A,
+  oslash: 0x00F8,
+  oslashacute: 0x01FF,
+  osmallhiragana: 0x3049,
+  osmallkatakana: 0x30A9,
+  osmallkatakanahalfwidth: 0xFF6B,
+  ostrokeacute: 0x01FF,
+  osuperior: 0xF6F0,
+  otcyrillic: 0x047F,
+  otilde: 0x00F5,
+  otildeacute: 0x1E4D,
+  otildedieresis: 0x1E4F,
+  oubopomofo: 0x3121,
+  overline: 0x203E,
+  overlinecenterline: 0xFE4A,
+  overlinecmb: 0x0305,
+  overlinedashed: 0xFE49,
+  overlinedblwavy: 0xFE4C,
+  overlinewavy: 0xFE4B,
+  overscore: 0x00AF,
+  ovowelsignbengali: 0x09CB,
+  ovowelsigndeva: 0x094B,
+  ovowelsigngujarati: 0x0ACB,
+  p: 0x0070,
+  paampssquare: 0x3380,
+  paasentosquare: 0x332B,
+  pabengali: 0x09AA,
+  pacute: 0x1E55,
+  padeva: 0x092A,
+  pagedown: 0x21DF,
+  pageup: 0x21DE,
+  pagujarati: 0x0AAA,
+  pagurmukhi: 0x0A2A,
+  pahiragana: 0x3071,
+  paiyannoithai: 0x0E2F,
+  pakatakana: 0x30D1,
+  palatalizationcyrilliccmb: 0x0484,
+  palochkacyrillic: 0x04C0,
+  pansioskorean: 0x317F,
+  paragraph: 0x00B6,
+  parallel: 0x2225,
+  parenleft: 0x0028,
+  parenleftaltonearabic: 0xFD3E,
+  parenleftbt: 0xF8ED,
+  parenleftex: 0xF8EC,
+  parenleftinferior: 0x208D,
+  parenleftmonospace: 0xFF08,
+  parenleftsmall: 0xFE59,
+  parenleftsuperior: 0x207D,
+  parenlefttp: 0xF8EB,
+  parenleftvertical: 0xFE35,
+  parenright: 0x0029,
+  parenrightaltonearabic: 0xFD3F,
+  parenrightbt: 0xF8F8,
+  parenrightex: 0xF8F7,
+  parenrightinferior: 0x208E,
+  parenrightmonospace: 0xFF09,
+  parenrightsmall: 0xFE5A,
+  parenrightsuperior: 0x207E,
+  parenrighttp: 0xF8F6,
+  parenrightvertical: 0xFE36,
+  partialdiff: 0x2202,
+  paseqhebrew: 0x05C0,
+  pashtahebrew: 0x0599,
+  pasquare: 0x33A9,
+  patah: 0x05B7,
+  patah11: 0x05B7,
+  patah1d: 0x05B7,
+  patah2a: 0x05B7,
+  patahhebrew: 0x05B7,
+  patahnarrowhebrew: 0x05B7,
+  patahquarterhebrew: 0x05B7,
+  patahwidehebrew: 0x05B7,
+  pazerhebrew: 0x05A1,
+  pbopomofo: 0x3106,
+  pcircle: 0x24DF,
+  pdotaccent: 0x1E57,
+  pe: 0x05E4,
+  pecyrillic: 0x043F,
+  pedagesh: 0xFB44,
+  pedageshhebrew: 0xFB44,
+  peezisquare: 0x333B,
+  pefinaldageshhebrew: 0xFB43,
+  peharabic: 0x067E,
+  peharmenian: 0x057A,
+  pehebrew: 0x05E4,
+  pehfinalarabic: 0xFB57,
+  pehinitialarabic: 0xFB58,
+  pehiragana: 0x307A,
+  pehmedialarabic: 0xFB59,
+  pekatakana: 0x30DA,
+  pemiddlehookcyrillic: 0x04A7,
+  perafehebrew: 0xFB4E,
+  percent: 0x0025,
+  percentarabic: 0x066A,
+  percentmonospace: 0xFF05,
+  percentsmall: 0xFE6A,
+  period: 0x002E,
+  periodarmenian: 0x0589,
+  periodcentered: 0x00B7,
+  periodhalfwidth: 0xFF61,
+  periodinferior: 0xF6E7,
+  periodmonospace: 0xFF0E,
+  periodsmall: 0xFE52,
+  periodsuperior: 0xF6E8,
+  perispomenigreekcmb: 0x0342,
+  perpendicular: 0x22A5,
+  perthousand: 0x2030,
+  peseta: 0x20A7,
+  pfsquare: 0x338A,
+  phabengali: 0x09AB,
+  phadeva: 0x092B,
+  phagujarati: 0x0AAB,
+  phagurmukhi: 0x0A2B,
+  phi: 0x03C6,
+  phi1: 0x03D5,
+  phieuphacirclekorean: 0x327A,
+  phieuphaparenkorean: 0x321A,
+  phieuphcirclekorean: 0x326C,
+  phieuphkorean: 0x314D,
+  phieuphparenkorean: 0x320C,
+  philatin: 0x0278,
+  phinthuthai: 0x0E3A,
+  phisymbolgreek: 0x03D5,
+  phook: 0x01A5,
+  phophanthai: 0x0E1E,
+  phophungthai: 0x0E1C,
+  phosamphaothai: 0x0E20,
+  pi: 0x03C0,
+  pieupacirclekorean: 0x3273,
+  pieupaparenkorean: 0x3213,
+  pieupcieuckorean: 0x3176,
+  pieupcirclekorean: 0x3265,
+  pieupkiyeokkorean: 0x3172,
+  pieupkorean: 0x3142,
+  pieupparenkorean: 0x3205,
+  pieupsioskiyeokkorean: 0x3174,
+  pieupsioskorean: 0x3144,
+  pieupsiostikeutkorean: 0x3175,
+  pieupthieuthkorean: 0x3177,
+  pieuptikeutkorean: 0x3173,
+  pihiragana: 0x3074,
+  pikatakana: 0x30D4,
+  pisymbolgreek: 0x03D6,
+  piwrarmenian: 0x0583,
+  plus: 0x002B,
+  plusbelowcmb: 0x031F,
+  pluscircle: 0x2295,
+  plusminus: 0x00B1,
+  plusmod: 0x02D6,
+  plusmonospace: 0xFF0B,
+  plussmall: 0xFE62,
+  plussuperior: 0x207A,
+  pmonospace: 0xFF50,
+  pmsquare: 0x33D8,
+  pohiragana: 0x307D,
+  pointingindexdownwhite: 0x261F,
+  pointingindexleftwhite: 0x261C,
+  pointingindexrightwhite: 0x261E,
+  pointingindexupwhite: 0x261D,
+  pokatakana: 0x30DD,
+  poplathai: 0x0E1B,
+  postalmark: 0x3012,
+  postalmarkface: 0x3020,
+  pparen: 0x24AB,
+  precedes: 0x227A,
+  prescription: 0x211E,
+  primemod: 0x02B9,
+  primereversed: 0x2035,
+  product: 0x220F,
+  projective: 0x2305,
+  prolongedkana: 0x30FC,
+  propellor: 0x2318,
+  propersubset: 0x2282,
+  propersuperset: 0x2283,
+  proportion: 0x2237,
+  proportional: 0x221D,
+  psi: 0x03C8,
+  psicyrillic: 0x0471,
+  psilipneumatacyrilliccmb: 0x0486,
+  pssquare: 0x33B0,
+  puhiragana: 0x3077,
+  pukatakana: 0x30D7,
+  pvsquare: 0x33B4,
+  pwsquare: 0x33BA,
+  q: 0x0071,
+  qadeva: 0x0958,
+  qadmahebrew: 0x05A8,
+  qafarabic: 0x0642,
+  qaffinalarabic: 0xFED6,
+  qafinitialarabic: 0xFED7,
+  qafmedialarabic: 0xFED8,
+  qamats: 0x05B8,
+  qamats10: 0x05B8,
+  qamats1a: 0x05B8,
+  qamats1c: 0x05B8,
+  qamats27: 0x05B8,
+  qamats29: 0x05B8,
+  qamats33: 0x05B8,
+  qamatsde: 0x05B8,
+  qamatshebrew: 0x05B8,
+  qamatsnarrowhebrew: 0x05B8,
+  qamatsqatanhebrew: 0x05B8,
+  qamatsqatannarrowhebrew: 0x05B8,
+  qamatsqatanquarterhebrew: 0x05B8,
+  qamatsqatanwidehebrew: 0x05B8,
+  qamatsquarterhebrew: 0x05B8,
+  qamatswidehebrew: 0x05B8,
+  qarneyparahebrew: 0x059F,
+  qbopomofo: 0x3111,
+  qcircle: 0x24E0,
+  qhook: 0x02A0,
+  qmonospace: 0xFF51,
+  qof: 0x05E7,
+  qofdagesh: 0xFB47,
+  qofdageshhebrew: 0xFB47,
+  qofhatafpatah: "05E7 05B2",
+  qofhatafpatahhebrew: "05E7 05B2",
+  qofhatafsegol: "05E7 05B1",
+  qofhatafsegolhebrew: "05E7 05B1",
+  qofhebrew: 0x05E7,
+  qofhiriq: "05E7 05B4",
+  qofhiriqhebrew: "05E7 05B4",
+  qofholam: "05E7 05B9",
+  qofholamhebrew: "05E7 05B9",
+  qofpatah: "05E7 05B7",
+  qofpatahhebrew: "05E7 05B7",
+  qofqamats: "05E7 05B8",
+  qofqamatshebrew: "05E7 05B8",
+  qofqubuts: "05E7 05BB",
+  qofqubutshebrew: "05E7 05BB",
+  qofsegol: "05E7 05B6",
+  qofsegolhebrew: "05E7 05B6",
+  qofsheva: "05E7 05B0",
+  qofshevahebrew: "05E7 05B0",
+  qoftsere: "05E7 05B5",
+  qoftserehebrew: "05E7 05B5",
+  qparen: 0x24AC,
+  quarternote: 0x2669,
+  qubuts: 0x05BB,
+  qubuts18: 0x05BB,
+  qubuts25: 0x05BB,
+  qubuts31: 0x05BB,
+  qubutshebrew: 0x05BB,
+  qubutsnarrowhebrew: 0x05BB,
+  qubutsquarterhebrew: 0x05BB,
+  qubutswidehebrew: 0x05BB,
+  question: 0x003F,
+  questionarabic: 0x061F,
+  questionarmenian: 0x055E,
+  questiondown: 0x00BF,
+  questiondownsmall: 0xF7BF,
+  questiongreek: 0x037E,
+  questionmonospace: 0xFF1F,
+  questionsmall: 0xF73F,
+  quotedbl: 0x0022,
+  quotedblbase: 0x201E,
+  quotedblleft: 0x201C,
+  quotedblmonospace: 0xFF02,
+  quotedblprime: 0x301E,
+  quotedblprimereversed: 0x301D,
+  quotedblright: 0x201D,
+  quoteleft: 0x2018,
+  quoteleftreversed: 0x201B,
+  quotereversed: 0x201B,
+  quoteright: 0x2019,
+  quoterightn: 0x0149,
+  quotesinglbase: 0x201A,
+  quotesingle: 0x0027,
+  quotesinglemonospace: 0xFF07,
+  r: 0x0072,
+  raarmenian: 0x057C,
+  rabengali: 0x09B0,
+  racute: 0x0155,
+  radeva: 0x0930,
+  radical: 0x221A,
+  radicalex: 0xF8E5,
+  radoverssquare: 0x33AE,
+  radoverssquaredsquare: 0x33AF,
+  radsquare: 0x33AD,
+  rafe: 0x05BF,
+  rafehebrew: 0x05BF,
+  ragujarati: 0x0AB0,
+  ragurmukhi: 0x0A30,
+  rahiragana: 0x3089,
+  rakatakana: 0x30E9,
+  rakatakanahalfwidth: 0xFF97,
+  ralowerdiagonalbengali: 0x09F1,
+  ramiddlediagonalbengali: 0x09F0,
+  ramshorn: 0x0264,
+  ratio: 0x2236,
+  rbopomofo: 0x3116,
+  rcaron: 0x0159,
+  rcedilla: 0x0157,
+  rcircle: 0x24E1,
+  rcommaaccent: 0x0157,
+  rdblgrave: 0x0211,
+  rdotaccent: 0x1E59,
+  rdotbelow: 0x1E5B,
+  rdotbelowmacron: 0x1E5D,
+  referencemark: 0x203B,
+  reflexsubset: 0x2286,
+  reflexsuperset: 0x2287,
+  registered: 0x00AE,
+  registersans: 0xF8E8,
+  registerserif: 0xF6DA,
+  reharabic: 0x0631,
+  reharmenian: 0x0580,
+  rehfinalarabic: 0xFEAE,
+  rehiragana: 0x308C,
+  rehyehaleflamarabic: "0631 FEF3 FE8E 0644",
+  rekatakana: 0x30EC,
+  rekatakanahalfwidth: 0xFF9A,
+  resh: 0x05E8,
+  reshdageshhebrew: 0xFB48,
+  reshhatafpatah: "05E8 05B2",
+  reshhatafpatahhebrew: "05E8 05B2",
+  reshhatafsegol: "05E8 05B1",
+  reshhatafsegolhebrew: "05E8 05B1",
+  reshhebrew: 0x05E8,
+  reshhiriq: "05E8 05B4",
+  reshhiriqhebrew: "05E8 05B4",
+  reshholam: "05E8 05B9",
+  reshholamhebrew: "05E8 05B9",
+  reshpatah: "05E8 05B7",
+  reshpatahhebrew: "05E8 05B7",
+  reshqamats: "05E8 05B8",
+  reshqamatshebrew: "05E8 05B8",
+  reshqubuts: "05E8 05BB",
+  reshqubutshebrew: "05E8 05BB",
+  reshsegol: "05E8 05B6",
+  reshsegolhebrew: "05E8 05B6",
+  reshsheva: "05E8 05B0",
+  reshshevahebrew: "05E8 05B0",
+  reshtsere: "05E8 05B5",
+  reshtserehebrew: "05E8 05B5",
+  reversedtilde: 0x223D,
+  reviahebrew: 0x0597,
+  reviamugrashhebrew: 0x0597,
+  revlogicalnot: 0x2310,
+  rfishhook: 0x027E,
+  rfishhookreversed: 0x027F,
+  rhabengali: 0x09DD,
+  rhadeva: 0x095D,
+  rho: 0x03C1,
+  rhook: 0x027D,
+  rhookturned: 0x027B,
+  rhookturnedsuperior: 0x02B5,
+  rhosymbolgreek: 0x03F1,
+  rhotichookmod: 0x02DE,
+  rieulacirclekorean: 0x3271,
+  rieulaparenkorean: 0x3211,
+  rieulcirclekorean: 0x3263,
+  rieulhieuhkorean: 0x3140,
+  rieulkiyeokkorean: 0x313A,
+  rieulkiyeoksioskorean: 0x3169,
+  rieulkorean: 0x3139,
+  rieulmieumkorean: 0x313B,
+  rieulpansioskorean: 0x316C,
+  rieulparenkorean: 0x3203,
+  rieulphieuphkorean: 0x313F,
+  rieulpieupkorean: 0x313C,
+  rieulpieupsioskorean: 0x316B,
+  rieulsioskorean: 0x313D,
+  rieulthieuthkorean: 0x313E,
+  rieultikeutkorean: 0x316A,
+  rieulyeorinhieuhkorean: 0x316D,
+  rightangle: 0x221F,
+  righttackbelowcmb: 0x0319,
+  righttriangle: 0x22BF,
+  rihiragana: 0x308A,
+  rikatakana: 0x30EA,
+  rikatakanahalfwidth: 0xFF98,
+  ring: 0x02DA,
+  ringbelowcmb: 0x0325,
+  ringcmb: 0x030A,
+  ringhalfleft: 0x02BF,
+  ringhalfleftarmenian: 0x0559,
+  ringhalfleftbelowcmb: 0x031C,
+  ringhalfleftcentered: 0x02D3,
+  ringhalfright: 0x02BE,
+  ringhalfrightbelowcmb: 0x0339,
+  ringhalfrightcentered: 0x02D2,
+  rinvertedbreve: 0x0213,
+  rittorusquare: 0x3351,
+  rlinebelow: 0x1E5F,
+  rlongleg: 0x027C,
+  rlonglegturned: 0x027A,
+  rmonospace: 0xFF52,
+  rohiragana: 0x308D,
+  rokatakana: 0x30ED,
+  rokatakanahalfwidth: 0xFF9B,
+  roruathai: 0x0E23,
+  rparen: 0x24AD,
+  rrabengali: 0x09DC,
+  rradeva: 0x0931,
+  rragurmukhi: 0x0A5C,
+  rreharabic: 0x0691,
+  rrehfinalarabic: 0xFB8D,
+  rrvocalicbengali: 0x09E0,
+  rrvocalicdeva: 0x0960,
+  rrvocalicgujarati: 0x0AE0,
+  rrvocalicvowelsignbengali: 0x09C4,
+  rrvocalicvowelsigndeva: 0x0944,
+  rrvocalicvowelsigngujarati: 0x0AC4,
+  rsuperior: 0xF6F1,
+  rtblock: 0x2590,
+  rturned: 0x0279,
+  rturnedsuperior: 0x02B4,
+  ruhiragana: 0x308B,
+  rukatakana: 0x30EB,
+  rukatakanahalfwidth: 0xFF99,
+  rupeemarkbengali: 0x09F2,
+  rupeesignbengali: 0x09F3,
+  rupiah: 0xF6DD,
+  ruthai: 0x0E24,
+  rvocalicbengali: 0x098B,
+  rvocalicdeva: 0x090B,
+  rvocalicgujarati: 0x0A8B,
+  rvocalicvowelsignbengali: 0x09C3,
+  rvocalicvowelsigndeva: 0x0943,
+  rvocalicvowelsigngujarati: 0x0AC3,
+  s: 0x0073,
+  sabengali: 0x09B8,
+  sacute: 0x015B,
+  sacutedotaccent: 0x1E65,
+  sadarabic: 0x0635,
+  sadeva: 0x0938,
+  sadfinalarabic: 0xFEBA,
+  sadinitialarabic: 0xFEBB,
+  sadmedialarabic: 0xFEBC,
+  sagujarati: 0x0AB8,
+  sagurmukhi: 0x0A38,
+  sahiragana: 0x3055,
+  sakatakana: 0x30B5,
+  sakatakanahalfwidth: 0xFF7B,
+  sallallahoualayhewasallamarabic: 0xFDFA,
+  samekh: 0x05E1,
+  samekhdagesh: 0xFB41,
+  samekhdageshhebrew: 0xFB41,
+  samekhhebrew: 0x05E1,
+  saraaathai: 0x0E32,
+  saraaethai: 0x0E41,
+  saraaimaimalaithai: 0x0E44,
+  saraaimaimuanthai: 0x0E43,
+  saraamthai: 0x0E33,
+  saraathai: 0x0E30,
+  saraethai: 0x0E40,
+  saraiileftthai: 0xF886,
+  saraiithai: 0x0E35,
+  saraileftthai: 0xF885,
+  saraithai: 0x0E34,
+  saraothai: 0x0E42,
+  saraueeleftthai: 0xF888,
+  saraueethai: 0x0E37,
+  saraueleftthai: 0xF887,
+  sarauethai: 0x0E36,
+  sarauthai: 0x0E38,
+  sarauuthai: 0x0E39,
+  sbopomofo: 0x3119,
+  scaron: 0x0161,
+  scarondotaccent: 0x1E67,
+  scedilla: 0x015F,
+  schwa: 0x0259,
+  schwacyrillic: 0x04D9,
+  schwadieresiscyrillic: 0x04DB,
+  schwahook: 0x025A,
+  scircle: 0x24E2,
+  scircumflex: 0x015D,
+  scommaaccent: 0x0219,
+  sdotaccent: 0x1E61,
+  sdotbelow: 0x1E63,
+  sdotbelowdotaccent: 0x1E69,
+  seagullbelowcmb: 0x033C,
+  second: 0x2033,
+  secondtonechinese: 0x02CA,
+  section: 0x00A7,
+  seenarabic: 0x0633,
+  seenfinalarabic: 0xFEB2,
+  seeninitialarabic: 0xFEB3,
+  seenmedialarabic: 0xFEB4,
+  segol: 0x05B6,
+  segol13: 0x05B6,
+  segol1f: 0x05B6,
+  segol2c: 0x05B6,
+  segolhebrew: 0x05B6,
+  segolnarrowhebrew: 0x05B6,
+  segolquarterhebrew: 0x05B6,
+  segoltahebrew: 0x0592,
+  segolwidehebrew: 0x05B6,
+  seharmenian: 0x057D,
+  sehiragana: 0x305B,
+  sekatakana: 0x30BB,
+  sekatakanahalfwidth: 0xFF7E,
+  semicolon: 0x003B,
+  semicolonarabic: 0x061B,
+  semicolonmonospace: 0xFF1B,
+  semicolonsmall: 0xFE54,
+  semivoicedmarkkana: 0x309C,
+  semivoicedmarkkanahalfwidth: 0xFF9F,
+  sentisquare: 0x3322,
+  sentosquare: 0x3323,
+  seven: 0x0037,
+  sevenarabic: 0x0667,
+  sevenbengali: 0x09ED,
+  sevencircle: 0x2466,
+  sevencircleinversesansserif: 0x2790,
+  sevendeva: 0x096D,
+  seveneighths: 0x215E,
+  sevengujarati: 0x0AED,
+  sevengurmukhi: 0x0A6D,
+  sevenhackarabic: 0x0667,
+  sevenhangzhou: 0x3027,
+  sevenideographicparen: 0x3226,
+  seveninferior: 0x2087,
+  sevenmonospace: 0xFF17,
+  sevenoldstyle: 0xF737,
+  sevenparen: 0x247A,
+  sevenperiod: 0x248E,
+  sevenpersian: 0x06F7,
+  sevenroman: 0x2176,
+  sevensuperior: 0x2077,
+  seventeencircle: 0x2470,
+  seventeenparen: 0x2484,
+  seventeenperiod: 0x2498,
+  seventhai: 0x0E57,
+  sfthyphen: 0x00AD,
+  shaarmenian: 0x0577,
+  shabengali: 0x09B6,
+  shacyrillic: 0x0448,
+  shaddaarabic: 0x0651,
+  shaddadammaarabic: 0xFC61,
+  shaddadammatanarabic: 0xFC5E,
+  shaddafathaarabic: 0xFC60,
+  shaddafathatanarabic: "0651 064B",
+  shaddakasraarabic: 0xFC62,
+  shaddakasratanarabic: 0xFC5F,
+  shade: 0x2592,
+  shadedark: 0x2593,
+  shadelight: 0x2591,
+  shademedium: 0x2592,
+  shadeva: 0x0936,
+  shagujarati: 0x0AB6,
+  shagurmukhi: 0x0A36,
+  shalshelethebrew: 0x0593,
+  shbopomofo: 0x3115,
+  shchacyrillic: 0x0449,
+  sheenarabic: 0x0634,
+  sheenfinalarabic: 0xFEB6,
+  sheeninitialarabic: 0xFEB7,
+  sheenmedialarabic: 0xFEB8,
+  sheicoptic: 0x03E3,
+  sheqel: 0x20AA,
+  sheqelhebrew: 0x20AA,
+  sheva: 0x05B0,
+  sheva115: 0x05B0,
+  sheva15: 0x05B0,
+  sheva22: 0x05B0,
+  sheva2e: 0x05B0,
+  shevahebrew: 0x05B0,
+  shevanarrowhebrew: 0x05B0,
+  shevaquarterhebrew: 0x05B0,
+  shevawidehebrew: 0x05B0,
+  shhacyrillic: 0x04BB,
+  shimacoptic: 0x03ED,
+  shin: 0x05E9,
+  shindagesh: 0xFB49,
+  shindageshhebrew: 0xFB49,
+  shindageshshindot: 0xFB2C,
+  shindageshshindothebrew: 0xFB2C,
+  shindageshsindot: 0xFB2D,
+  shindageshsindothebrew: 0xFB2D,
+  shindothebrew: 0x05C1,
+  shinhebrew: 0x05E9,
+  shinshindot: 0xFB2A,
+  shinshindothebrew: 0xFB2A,
+  shinsindot: 0xFB2B,
+  shinsindothebrew: 0xFB2B,
+  shook: 0x0282,
+  sigma: 0x03C3,
+  sigma1: 0x03C2,
+  sigmafinal: 0x03C2,
+  sigmalunatesymbolgreek: 0x03F2,
+  sihiragana: 0x3057,
+  sikatakana: 0x30B7,
+  sikatakanahalfwidth: 0xFF7C,
+  siluqhebrew: 0x05BD,
+  siluqlefthebrew: 0x05BD,
+  similar: 0x223C,
+  sindothebrew: 0x05C2,
+  siosacirclekorean: 0x3274,
+  siosaparenkorean: 0x3214,
+  sioscieuckorean: 0x317E,
+  sioscirclekorean: 0x3266,
+  sioskiyeokkorean: 0x317A,
+  sioskorean: 0x3145,
+  siosnieunkorean: 0x317B,
+  siosparenkorean: 0x3206,
+  siospieupkorean: 0x317D,
+  siostikeutkorean: 0x317C,
+  six: 0x0036,
+  sixarabic: 0x0666,
+  sixbengali: 0x09EC,
+  sixcircle: 0x2465,
+  sixcircleinversesansserif: 0x278F,
+  sixdeva: 0x096C,
+  sixgujarati: 0x0AEC,
+  sixgurmukhi: 0x0A6C,
+  sixhackarabic: 0x0666,
+  sixhangzhou: 0x3026,
+  sixideographicparen: 0x3225,
+  sixinferior: 0x2086,
+  sixmonospace: 0xFF16,
+  sixoldstyle: 0xF736,
+  sixparen: 0x2479,
+  sixperiod: 0x248D,
+  sixpersian: 0x06F6,
+  sixroman: 0x2175,
+  sixsuperior: 0x2076,
+  sixteencircle: 0x246F,
+  sixteencurrencydenominatorbengali: 0x09F9,
+  sixteenparen: 0x2483,
+  sixteenperiod: 0x2497,
+  sixthai: 0x0E56,
+  slash: 0x002F,
+  slashmonospace: 0xFF0F,
+  slong: 0x017F,
+  slongdotaccent: 0x1E9B,
+  smileface: 0x263A,
+  smonospace: 0xFF53,
+  sofpasuqhebrew: 0x05C3,
+  softhyphen: 0x00AD,
+  softsigncyrillic: 0x044C,
+  sohiragana: 0x305D,
+  sokatakana: 0x30BD,
+  sokatakanahalfwidth: 0xFF7F,
+  soliduslongoverlaycmb: 0x0338,
+  solidusshortoverlaycmb: 0x0337,
+  sorusithai: 0x0E29,
+  sosalathai: 0x0E28,
+  sosothai: 0x0E0B,
+  sosuathai: 0x0E2A,
+  space: 0x0020,
+  spacehackarabic: 0x0020,
+  spade: 0x2660,
+  spadesuitblack: 0x2660,
+  spadesuitwhite: 0x2664,
+  sparen: 0x24AE,
+  squarebelowcmb: 0x033B,
+  squarecc: 0x33C4,
+  squarecm: 0x339D,
+  squarediagonalcrosshatchfill: 0x25A9,
+  squarehorizontalfill: 0x25A4,
+  squarekg: 0x338F,
+  squarekm: 0x339E,
+  squarekmcapital: 0x33CE,
+  squareln: 0x33D1,
+  squarelog: 0x33D2,
+  squaremg: 0x338E,
+  squaremil: 0x33D5,
+  squaremm: 0x339C,
+  squaremsquared: 0x33A1,
+  squareorthogonalcrosshatchfill: 0x25A6,
+  squareupperlefttolowerrightfill: 0x25A7,
+  squareupperrighttolowerleftfill: 0x25A8,
+  squareverticalfill: 0x25A5,
+  squarewhitewithsmallblack: 0x25A3,
+  srsquare: 0x33DB,
+  ssabengali: 0x09B7,
+  ssadeva: 0x0937,
+  ssagujarati: 0x0AB7,
+  ssangcieuckorean: 0x3149,
+  ssanghieuhkorean: 0x3185,
+  ssangieungkorean: 0x3180,
+  ssangkiyeokkorean: 0x3132,
+  ssangnieunkorean: 0x3165,
+  ssangpieupkorean: 0x3143,
+  ssangsioskorean: 0x3146,
+  ssangtikeutkorean: 0x3138,
+  ssuperior: 0xF6F2,
+  sterling: 0x00A3,
+  sterlingmonospace: 0xFFE1,
+  strokelongoverlaycmb: 0x0336,
+  strokeshortoverlaycmb: 0x0335,
+  subset: 0x2282,
+  subsetnotequal: 0x228A,
+  subsetorequal: 0x2286,
+  succeeds: 0x227B,
+  suchthat: 0x220B,
+  suhiragana: 0x3059,
+  sukatakana: 0x30B9,
+  sukatakanahalfwidth: 0xFF7D,
+  sukunarabic: 0x0652,
+  summation: 0x2211,
+  sun: 0x263C,
+  superset: 0x2283,
+  supersetnotequal: 0x228B,
+  supersetorequal: 0x2287,
+  svsquare: 0x33DC,
+  syouwaerasquare: 0x337C,
+  t: 0x0074,
+  tabengali: 0x09A4,
+  tackdown: 0x22A4,
+  tackleft: 0x22A3,
+  tadeva: 0x0924,
+  tagujarati: 0x0AA4,
+  tagurmukhi: 0x0A24,
+  taharabic: 0x0637,
+  tahfinalarabic: 0xFEC2,
+  tahinitialarabic: 0xFEC3,
+  tahiragana: 0x305F,
+  tahmedialarabic: 0xFEC4,
+  taisyouerasquare: 0x337D,
+  takatakana: 0x30BF,
+  takatakanahalfwidth: 0xFF80,
+  tatweelarabic: 0x0640,
+  tau: 0x03C4,
+  tav: 0x05EA,
+  tavdages: 0xFB4A,
+  tavdagesh: 0xFB4A,
+  tavdageshhebrew: 0xFB4A,
+  tavhebrew: 0x05EA,
+  tbar: 0x0167,
+  tbopomofo: 0x310A,
+  tcaron: 0x0165,
+  tccurl: 0x02A8,
+  tcedilla: 0x0163,
+  tcheharabic: 0x0686,
+  tchehfinalarabic: 0xFB7B,
+  tchehinitialarabic: 0xFB7C,
+  tchehmedialarabic: 0xFB7D,
+  tchehmeeminitialarabic: "FB7C FEE4",
+  tcircle: 0x24E3,
+  tcircumflexbelow: 0x1E71,
+  tcommaaccent: 0x0163,
+  tdieresis: 0x1E97,
+  tdotaccent: 0x1E6B,
+  tdotbelow: 0x1E6D,
+  tecyrillic: 0x0442,
+  tedescendercyrillic: 0x04AD,
+  teharabic: 0x062A,
+  tehfinalarabic: 0xFE96,
+  tehhahinitialarabic: 0xFCA2,
+  tehhahisolatedarabic: 0xFC0C,
+  tehinitialarabic: 0xFE97,
+  tehiragana: 0x3066,
+  tehjeeminitialarabic: 0xFCA1,
+  tehjeemisolatedarabic: 0xFC0B,
+  tehmarbutaarabic: 0x0629,
+  tehmarbutafinalarabic: 0xFE94,
+  tehmedialarabic: 0xFE98,
+  tehmeeminitialarabic: 0xFCA4,
+  tehmeemisolatedarabic: 0xFC0E,
+  tehnoonfinalarabic: 0xFC73,
+  tekatakana: 0x30C6,
+  tekatakanahalfwidth: 0xFF83,
+  telephone: 0x2121,
+  telephoneblack: 0x260E,
+  telishagedolahebrew: 0x05A0,
+  telishaqetanahebrew: 0x05A9,
+  tencircle: 0x2469,
+  tenideographicparen: 0x3229,
+  tenparen: 0x247D,
+  tenperiod: 0x2491,
+  tenroman: 0x2179,
+  tesh: 0x02A7,
+  tet: 0x05D8,
+  tetdagesh: 0xFB38,
+  tetdageshhebrew: 0xFB38,
+  tethebrew: 0x05D8,
+  tetsecyrillic: 0x04B5,
+  tevirhebrew: 0x059B,
+  tevirlefthebrew: 0x059B,
+  thabengali: 0x09A5,
+  thadeva: 0x0925,
+  thagujarati: 0x0AA5,
+  thagurmukhi: 0x0A25,
+  thalarabic: 0x0630,
+  thalfinalarabic: 0xFEAC,
+  thanthakhatlowleftthai: 0xF898,
+  thanthakhatlowrightthai: 0xF897,
+  thanthakhatthai: 0x0E4C,
+  thanthakhatupperleftthai: 0xF896,
+  theharabic: 0x062B,
+  thehfinalarabic: 0xFE9A,
+  thehinitialarabic: 0xFE9B,
+  thehmedialarabic: 0xFE9C,
+  thereexists: 0x2203,
+  therefore: 0x2234,
+  theta: 0x03B8,
+  theta1: 0x03D1,
+  thetasymbolgreek: 0x03D1,
+  thieuthacirclekorean: 0x3279,
+  thieuthaparenkorean: 0x3219,
+  thieuthcirclekorean: 0x326B,
+  thieuthkorean: 0x314C,
+  thieuthparenkorean: 0x320B,
+  thirteencircle: 0x246C,
+  thirteenparen: 0x2480,
+  thirteenperiod: 0x2494,
+  thonangmonthothai: 0x0E11,
+  thook: 0x01AD,
+  thophuthaothai: 0x0E12,
+  thorn: 0x00FE,
+  thothahanthai: 0x0E17,
+  thothanthai: 0x0E10,
+  thothongthai: 0x0E18,
+  thothungthai: 0x0E16,
+  thousandcyrillic: 0x0482,
+  thousandsseparatorarabic: 0x066C,
+  thousandsseparatorpersian: 0x066C,
+  three: 0x0033,
+  threearabic: 0x0663,
+  threebengali: 0x09E9,
+  threecircle: 0x2462,
+  threecircleinversesansserif: 0x278C,
+  threedeva: 0x0969,
+  threeeighths: 0x215C,
+  threegujarati: 0x0AE9,
+  threegurmukhi: 0x0A69,
+  threehackarabic: 0x0663,
+  threehangzhou: 0x3023,
+  threeideographicparen: 0x3222,
+  threeinferior: 0x2083,
+  threemonospace: 0xFF13,
+  threenumeratorbengali: 0x09F6,
+  threeoldstyle: 0xF733,
+  threeparen: 0x2476,
+  threeperiod: 0x248A,
+  threepersian: 0x06F3,
+  threequarters: 0x00BE,
+  threequartersemdash: 0xF6DE,
+  threeroman: 0x2172,
+  threesuperior: 0x00B3,
+  threethai: 0x0E53,
+  thzsquare: 0x3394,
+  tihiragana: 0x3061,
+  tikatakana: 0x30C1,
+  tikatakanahalfwidth: 0xFF81,
+  tikeutacirclekorean: 0x3270,
+  tikeutaparenkorean: 0x3210,
+  tikeutcirclekorean: 0x3262,
+  tikeutkorean: 0x3137,
+  tikeutparenkorean: 0x3202,
+  tilde: 0x02DC,
+  tildebelowcmb: 0x0330,
+  tildecmb: 0x0303,
+  tildecomb: 0x0303,
+  tildedoublecmb: 0x0360,
+  tildeoperator: 0x223C,
+  tildeoverlaycmb: 0x0334,
+  tildeverticalcmb: 0x033E,
+  timescircle: 0x2297,
+  tipehahebrew: 0x0596,
+  tipehalefthebrew: 0x0596,
+  tippigurmukhi: 0x0A70,
+  titlocyrilliccmb: 0x0483,
+  tiwnarmenian: 0x057F,
+  tlinebelow: 0x1E6F,
+  tmonospace: 0xFF54,
+  toarmenian: 0x0569,
+  tohiragana: 0x3068,
+  tokatakana: 0x30C8,
+  tokatakanahalfwidth: 0xFF84,
+  tonebarextrahighmod: 0x02E5,
+  tonebarextralowmod: 0x02E9,
+  tonebarhighmod: 0x02E6,
+  tonebarlowmod: 0x02E8,
+  tonebarmidmod: 0x02E7,
+  tonefive: 0x01BD,
+  tonesix: 0x0185,
+  tonetwo: 0x01A8,
+  tonos: 0x0384,
+  tonsquare: 0x3327,
+  topatakthai: 0x0E0F,
+  tortoiseshellbracketleft: 0x3014,
+  tortoiseshellbracketleftsmall: 0xFE5D,
+  tortoiseshellbracketleftvertical: 0xFE39,
+  tortoiseshellbracketright: 0x3015,
+  tortoiseshellbracketrightsmall: 0xFE5E,
+  tortoiseshellbracketrightvertical: 0xFE3A,
+  totaothai: 0x0E15,
+  tpalatalhook: 0x01AB,
+  tparen: 0x24AF,
+  trademark: 0x2122,
+  trademarksans: 0xF8EA,
+  trademarkserif: 0xF6DB,
+  tretroflexhook: 0x0288,
+  triagdn: 0x25BC,
+  triaglf: 0x25C4,
+  triagrt: 0x25BA,
+  triagup: 0x25B2,
+  ts: 0x02A6,
+  tsadi: 0x05E6,
+  tsadidagesh: 0xFB46,
+  tsadidageshhebrew: 0xFB46,
+  tsadihebrew: 0x05E6,
+  tsecyrillic: 0x0446,
+  tsere: 0x05B5,
+  tsere12: 0x05B5,
+  tsere1e: 0x05B5,
+  tsere2b: 0x05B5,
+  tserehebrew: 0x05B5,
+  tserenarrowhebrew: 0x05B5,
+  tserequarterhebrew: 0x05B5,
+  tserewidehebrew: 0x05B5,
+  tshecyrillic: 0x045B,
+  tsuperior: 0xF6F3,
+  ttabengali: 0x099F,
+  ttadeva: 0x091F,
+  ttagujarati: 0x0A9F,
+  ttagurmukhi: 0x0A1F,
+  tteharabic: 0x0679,
+  ttehfinalarabic: 0xFB67,
+  ttehinitialarabic: 0xFB68,
+  ttehmedialarabic: 0xFB69,
+  tthabengali: 0x09A0,
+  tthadeva: 0x0920,
+  tthagujarati: 0x0AA0,
+  tthagurmukhi: 0x0A20,
+  tturned: 0x0287,
+  tuhiragana: 0x3064,
+  tukatakana: 0x30C4,
+  tukatakanahalfwidth: 0xFF82,
+  tusmallhiragana: 0x3063,
+  tusmallkatakana: 0x30C3,
+  tusmallkatakanahalfwidth: 0xFF6F,
+  twelvecircle: 0x246B,
+  twelveparen: 0x247F,
+  twelveperiod: 0x2493,
+  twelveroman: 0x217B,
+  twentycircle: 0x2473,
+  twentyhangzhou: 0x5344,
+  twentyparen: 0x2487,
+  twentyperiod: 0x249B,
+  two: 0x0032,
+  twoarabic: 0x0662,
+  twobengali: 0x09E8,
+  twocircle: 0x2461,
+  twocircleinversesansserif: 0x278B,
+  twodeva: 0x0968,
+  twodotenleader: 0x2025,
+  twodotleader: 0x2025,
+  twodotleadervertical: 0xFE30,
+  twogujarati: 0x0AE8,
+  twogurmukhi: 0x0A68,
+  twohackarabic: 0x0662,
+  twohangzhou: 0x3022,
+  twoideographicparen: 0x3221,
+  twoinferior: 0x2082,
+  twomonospace: 0xFF12,
+  twonumeratorbengali: 0x09F5,
+  twooldstyle: 0xF732,
+  twoparen: 0x2475,
+  twoperiod: 0x2489,
+  twopersian: 0x06F2,
+  tworoman: 0x2171,
+  twostroke: 0x01BB,
+  twosuperior: 0x00B2,
+  twothai: 0x0E52,
+  twothirds: 0x2154,
+  u: 0x0075,
+  uacute: 0x00FA,
+  ubar: 0x0289,
+  ubengali: 0x0989,
+  ubopomofo: 0x3128,
+  ubreve: 0x016D,
+  ucaron: 0x01D4,
+  ucircle: 0x24E4,
+  ucircumflex: 0x00FB,
+  ucircumflexbelow: 0x1E77,
+  ucyrillic: 0x0443,
+  udattadeva: 0x0951,
+  udblacute: 0x0171,
+  udblgrave: 0x0215,
+  udeva: 0x0909,
+  udieresis: 0x00FC,
+  udieresisacute: 0x01D8,
+  udieresisbelow: 0x1E73,
+  udieresiscaron: 0x01DA,
+  udieresiscyrillic: 0x04F1,
+  udieresisgrave: 0x01DC,
+  udieresismacron: 0x01D6,
+  udotbelow: 0x1EE5,
+  ugrave: 0x00F9,
+  ugujarati: 0x0A89,
+  ugurmukhi: 0x0A09,
+  uhiragana: 0x3046,
+  uhookabove: 0x1EE7,
+  uhorn: 0x01B0,
+  uhornacute: 0x1EE9,
+  uhorndotbelow: 0x1EF1,
+  uhorngrave: 0x1EEB,
+  uhornhookabove: 0x1EED,
+  uhorntilde: 0x1EEF,
+  uhungarumlaut: 0x0171,
+  uhungarumlautcyrillic: 0x04F3,
+  uinvertedbreve: 0x0217,
+  ukatakana: 0x30A6,
+  ukatakanahalfwidth: 0xFF73,
+  ukcyrillic: 0x0479,
+  ukorean: 0x315C,
+  umacron: 0x016B,
+  umacroncyrillic: 0x04EF,
+  umacrondieresis: 0x1E7B,
+  umatragurmukhi: 0x0A41,
+  umonospace: 0xFF55,
+  underscore: 0x005F,
+  underscoredbl: 0x2017,
+  underscoremonospace: 0xFF3F,
+  underscorevertical: 0xFE33,
+  underscorewavy: 0xFE4F,
+  union: 0x222A,
+  universal: 0x2200,
+  uogonek: 0x0173,
+  uparen: 0x24B0,
+  upblock: 0x2580,
+  upperdothebrew: 0x05C4,
+  upsilon: 0x03C5,
+  upsilondieresis: 0x03CB,
+  upsilondieresistonos: 0x03B0,
+  upsilonlatin: 0x028A,
+  upsilontonos: 0x03CD,
+  uptackbelowcmb: 0x031D,
+  uptackmod: 0x02D4,
+  uragurmukhi: 0x0A73,
+  uring: 0x016F,
+  ushortcyrillic: 0x045E,
+  usmallhiragana: 0x3045,
+  usmallkatakana: 0x30A5,
+  usmallkatakanahalfwidth: 0xFF69,
+  ustraightcyrillic: 0x04AF,
+  ustraightstrokecyrillic: 0x04B1,
+  utilde: 0x0169,
+  utildeacute: 0x1E79,
+  utildebelow: 0x1E75,
+  uubengali: 0x098A,
+  uudeva: 0x090A,
+  uugujarati: 0x0A8A,
+  uugurmukhi: 0x0A0A,
+  uumatragurmukhi: 0x0A42,
+  uuvowelsignbengali: 0x09C2,
+  uuvowelsigndeva: 0x0942,
+  uuvowelsigngujarati: 0x0AC2,
+  uvowelsignbengali: 0x09C1,
+  uvowelsigndeva: 0x0941,
+  uvowelsigngujarati: 0x0AC1,
+  v: 0x0076,
+  vadeva: 0x0935,
+  vagujarati: 0x0AB5,
+  vagurmukhi: 0x0A35,
+  vakatakana: 0x30F7,
+  vav: 0x05D5,
+  vavdagesh: 0xFB35,
+  vavdagesh65: 0xFB35,
+  vavdageshhebrew: 0xFB35,
+  vavhebrew: 0x05D5,
+  vavholam: 0xFB4B,
+  vavholamhebrew: 0xFB4B,
+  vavvavhebrew: 0x05F0,
+  vavyodhebrew: 0x05F1,
+  vcircle: 0x24E5,
+  vdotbelow: 0x1E7F,
+  vecyrillic: 0x0432,
+  veharabic: 0x06A4,
+  vehfinalarabic: 0xFB6B,
+  vehinitialarabic: 0xFB6C,
+  vehmedialarabic: 0xFB6D,
+  vekatakana: 0x30F9,
+  venus: 0x2640,
+  verticalbar: 0x007C,
+  verticallineabovecmb: 0x030D,
+  verticallinebelowcmb: 0x0329,
+  verticallinelowmod: 0x02CC,
+  verticallinemod: 0x02C8,
+  vewarmenian: 0x057E,
+  vhook: 0x028B,
+  vikatakana: 0x30F8,
+  viramabengali: 0x09CD,
+  viramadeva: 0x094D,
+  viramagujarati: 0x0ACD,
+  visargabengali: 0x0983,
+  visargadeva: 0x0903,
+  visargagujarati: 0x0A83,
+  vmonospace: 0xFF56,
+  voarmenian: 0x0578,
+  voicediterationhiragana: 0x309E,
+  voicediterationkatakana: 0x30FE,
+  voicedmarkkana: 0x309B,
+  voicedmarkkanahalfwidth: 0xFF9E,
+  vokatakana: 0x30FA,
+  vparen: 0x24B1,
+  vtilde: 0x1E7D,
+  vturned: 0x028C,
+  vuhiragana: 0x3094,
+  vukatakana: 0x30F4,
+  w: 0x0077,
+  wacute: 0x1E83,
+  waekorean: 0x3159,
+  wahiragana: 0x308F,
+  wakatakana: 0x30EF,
+  wakatakanahalfwidth: 0xFF9C,
+  wakorean: 0x3158,
+  wasmallhiragana: 0x308E,
+  wasmallkatakana: 0x30EE,
+  wattosquare: 0x3357,
+  wavedash: 0x301C,
+  wavyunderscorevertical: 0xFE34,
+  wawarabic: 0x0648,
+  wawfinalarabic: 0xFEEE,
+  wawhamzaabovearabic: 0x0624,
+  wawhamzaabovefinalarabic: 0xFE86,
+  wbsquare: 0x33DD,
+  wcircle: 0x24E6,
+  wcircumflex: 0x0175,
+  wdieresis: 0x1E85,
+  wdotaccent: 0x1E87,
+  wdotbelow: 0x1E89,
+  wehiragana: 0x3091,
+  weierstrass: 0x2118,
+  wekatakana: 0x30F1,
+  wekorean: 0x315E,
+  weokorean: 0x315D,
+  wgrave: 0x1E81,
+  whitebullet: 0x25E6,
+  whitecircle: 0x25CB,
+  whitecircleinverse: 0x25D9,
+  whitecornerbracketleft: 0x300E,
+  whitecornerbracketleftvertical: 0xFE43,
+  whitecornerbracketright: 0x300F,
+  whitecornerbracketrightvertical: 0xFE44,
+  whitediamond: 0x25C7,
+  whitediamondcontainingblacksmalldiamond: 0x25C8,
+  whitedownpointingsmalltriangle: 0x25BF,
+  whitedownpointingtriangle: 0x25BD,
+  whiteleftpointingsmalltriangle: 0x25C3,
+  whiteleftpointingtriangle: 0x25C1,
+  whitelenticularbracketleft: 0x3016,
+  whitelenticularbracketright: 0x3017,
+  whiterightpointingsmalltriangle: 0x25B9,
+  whiterightpointingtriangle: 0x25B7,
+  whitesmallsquare: 0x25AB,
+  whitesmilingface: 0x263A,
+  whitesquare: 0x25A1,
+  whitestar: 0x2606,
+  whitetelephone: 0x260F,
+  whitetortoiseshellbracketleft: 0x3018,
+  whitetortoiseshellbracketright: 0x3019,
+  whiteuppointingsmalltriangle: 0x25B5,
+  whiteuppointingtriangle: 0x25B3,
+  wihiragana: 0x3090,
+  wikatakana: 0x30F0,
+  wikorean: 0x315F,
+  wmonospace: 0xFF57,
+  wohiragana: 0x3092,
+  wokatakana: 0x30F2,
+  wokatakanahalfwidth: 0xFF66,
+  won: 0x20A9,
+  wonmonospace: 0xFFE6,
+  wowaenthai: 0x0E27,
+  wparen: 0x24B2,
+  wring: 0x1E98,
+  wsuperior: 0x02B7,
+  wturned: 0x028D,
+  wynn: 0x01BF,
+  x: 0x0078,
+  xabovecmb: 0x033D,
+  xbopomofo: 0x3112,
+  xcircle: 0x24E7,
+  xdieresis: 0x1E8D,
+  xdotaccent: 0x1E8B,
+  xeharmenian: 0x056D,
+  xi: 0x03BE,
+  xmonospace: 0xFF58,
+  xparen: 0x24B3,
+  xsuperior: 0x02E3,
+  y: 0x0079,
+  yaadosquare: 0x334E,
+  yabengali: 0x09AF,
+  yacute: 0x00FD,
+  yadeva: 0x092F,
+  yaekorean: 0x3152,
+  yagujarati: 0x0AAF,
+  yagurmukhi: 0x0A2F,
+  yahiragana: 0x3084,
+  yakatakana: 0x30E4,
+  yakatakanahalfwidth: 0xFF94,
+  yakorean: 0x3151,
+  yamakkanthai: 0x0E4E,
+  yasmallhiragana: 0x3083,
+  yasmallkatakana: 0x30E3,
+  yasmallkatakanahalfwidth: 0xFF6C,
+  yatcyrillic: 0x0463,
+  ycircle: 0x24E8,
+  ycircumflex: 0x0177,
+  ydieresis: 0x00FF,
+  ydotaccent: 0x1E8F,
+  ydotbelow: 0x1EF5,
+  yeharabic: 0x064A,
+  yehbarreearabic: 0x06D2,
+  yehbarreefinalarabic: 0xFBAF,
+  yehfinalarabic: 0xFEF2,
+  yehhamzaabovearabic: 0x0626,
+  yehhamzaabovefinalarabic: 0xFE8A,
+  yehhamzaaboveinitialarabic: 0xFE8B,
+  yehhamzaabovemedialarabic: 0xFE8C,
+  yehinitialarabic: 0xFEF3,
+  yehmedialarabic: 0xFEF4,
+  yehmeeminitialarabic: 0xFCDD,
+  yehmeemisolatedarabic: 0xFC58,
+  yehnoonfinalarabic: 0xFC94,
+  yehthreedotsbelowarabic: 0x06D1,
+  yekorean: 0x3156,
+  yen: 0x00A5,
+  yenmonospace: 0xFFE5,
+  yeokorean: 0x3155,
+  yeorinhieuhkorean: 0x3186,
+  yerahbenyomohebrew: 0x05AA,
+  yerahbenyomolefthebrew: 0x05AA,
+  yericyrillic: 0x044B,
+  yerudieresiscyrillic: 0x04F9,
+  yesieungkorean: 0x3181,
+  yesieungpansioskorean: 0x3183,
+  yesieungsioskorean: 0x3182,
+  yetivhebrew: 0x059A,
+  ygrave: 0x1EF3,
+  yhook: 0x01B4,
+  yhookabove: 0x1EF7,
+  yiarmenian: 0x0575,
+  yicyrillic: 0x0457,
+  yikorean: 0x3162,
+  yinyang: 0x262F,
+  yiwnarmenian: 0x0582,
+  ymonospace: 0xFF59,
+  yod: 0x05D9,
+  yoddagesh: 0xFB39,
+  yoddageshhebrew: 0xFB39,
+  yodhebrew: 0x05D9,
+  yodyodhebrew: 0x05F2,
+  yodyodpatahhebrew: 0xFB1F,
+  yohiragana: 0x3088,
+  yoikorean: 0x3189,
+  yokatakana: 0x30E8,
+  yokatakanahalfwidth: 0xFF96,
+  yokorean: 0x315B,
+  yosmallhiragana: 0x3087,
+  yosmallkatakana: 0x30E7,
+  yosmallkatakanahalfwidth: 0xFF6E,
+  yotgreek: 0x03F3,
+  yoyaekorean: 0x3188,
+  yoyakorean: 0x3187,
+  yoyakthai: 0x0E22,
+  yoyingthai: 0x0E0D,
+  yparen: 0x24B4,
+  ypogegrammeni: 0x037A,
+  ypogegrammenigreekcmb: 0x0345,
+  yr: 0x01A6,
+  yring: 0x1E99,
+  ysuperior: 0x02B8,
+  ytilde: 0x1EF9,
+  yturned: 0x028E,
+  yuhiragana: 0x3086,
+  yuikorean: 0x318C,
+  yukatakana: 0x30E6,
+  yukatakanahalfwidth: 0xFF95,
+  yukorean: 0x3160,
+  yusbigcyrillic: 0x046B,
+  yusbigiotifiedcyrillic: 0x046D,
+  yuslittlecyrillic: 0x0467,
+  yuslittleiotifiedcyrillic: 0x0469,
+  yusmallhiragana: 0x3085,
+  yusmallkatakana: 0x30E5,
+  yusmallkatakanahalfwidth: 0xFF6D,
+  yuyekorean: 0x318B,
+  yuyeokorean: 0x318A,
+  yyabengali: 0x09DF,
+  yyadeva: 0x095F,
+  z: 0x007A,
+  zaarmenian: 0x0566,
+  zacute: 0x017A,
+  zadeva: 0x095B,
+  zagurmukhi: 0x0A5B,
+  zaharabic: 0x0638,
+  zahfinalarabic: 0xFEC6,
+  zahinitialarabic: 0xFEC7,
+  zahiragana: 0x3056,
+  zahmedialarabic: 0xFEC8,
+  zainarabic: 0x0632,
+  zainfinalarabic: 0xFEB0,
+  zakatakana: 0x30B6,
+  zaqefgadolhebrew: 0x0595,
+  zaqefqatanhebrew: 0x0594,
+  zarqahebrew: 0x0598,
+  zayin: 0x05D6,
+  zayindagesh: 0xFB36,
+  zayindageshhebrew: 0xFB36,
+  zayinhebrew: 0x05D6,
+  zbopomofo: 0x3117,
+  zcaron: 0x017E,
+  zcircle: 0x24E9,
+  zcircumflex: 0x1E91,
+  zcurl: 0x0291,
+  zdot: 0x017C,
+  zdotaccent: 0x017C,
+  zdotbelow: 0x1E93,
+  zecyrillic: 0x0437,
+  zedescendercyrillic: 0x0499,
+  zedieresiscyrillic: 0x04DF,
+  zehiragana: 0x305C,
+  zekatakana: 0x30BC,
+  zero: 0x0030,
+  zeroarabic: 0x0660,
+  zerobengali: 0x09E6,
+  zerodeva: 0x0966,
+  zerogujarati: 0x0AE6,
+  zerogurmukhi: 0x0A66,
+  zerohackarabic: 0x0660,
+  zeroinferior: 0x2080,
+  zeromonospace: 0xFF10,
+  zerooldstyle: 0xF730,
+  zeropersian: 0x06F0,
+  zerosuperior: 0x2070,
+  zerothai: 0x0E50,
+  zerowidthjoiner: 0xFEFF,
+  zerowidthnonjoiner: 0x200C,
+  zerowidthspace: 0x200B,
+  zeta: 0x03B6,
+  zhbopomofo: 0x3113,
+  zhearmenian: 0x056A,
+  zhebrevecyrillic: 0x04C2,
+  zhecyrillic: 0x0436,
+  zhedescendercyrillic: 0x0497,
+  zhedieresiscyrillic: 0x04DD,
+  zihiragana: 0x3058,
+  zikatakana: 0x30B8,
+  zinorhebrew: 0x05AE,
+  zlinebelow: 0x1E95,
+  zmonospace: 0xFF5A,
+  zohiragana: 0x305E,
+  zokatakana: 0x30BE,
+  zparen: 0x24B5,
+  zretroflexhook: 0x0290,
+  zstroke: 0x01B6,
+  zuhiragana: 0x305A,
+  zukatakana: 0x30BA
+};
+
+// Add missing glyphs from the original Adobe's list
+GlyphsUnicode["angbracketleft"] = 0x3008;
+GlyphsUnicode["angbracketright"] = 0x3009;
+GlyphsUnicode["circlecopyrt"] = 0x00A9;
+
diff --git a/pdf.js b/pdf.js
index c2b8f160f..256e56adf 100644
--- a/pdf.js
+++ b/pdf.js
@@ -5,6 +5,7 @@ var ERRORS = 0, WARNINGS = 1, TODOS = 5;
 var verbosity = WARNINGS;
 
 function log(msg) {
+    msg = msg.toString ? msg.toString() : msg;
     if (console && console.log)
         console.log(msg);
     else if (print)
@@ -51,7 +52,7 @@ var Stream = (function() {
         this.bytes = new Uint8Array(arrayBuffer);
         this.start = start || 0;
         this.pos = this.start;
-        this.end = (start + length) || arrayBuffer.byteLength;
+        this.end = (start + length) || this.bytes.byteLength;
         this.dict = dict;
     }
 
@@ -92,7 +93,7 @@ var Stream = (function() {
             return ch;
         },
         skip: function(n) {
-            if (!n)
+            if (!n && !IsNum(n))
                 n = 1;
             this.pos += n;
         },
@@ -696,6 +697,9 @@ var Name = (function() {
     }
 
     constructor.prototype = {
+      toString: function() {
+        return this.name;
+      }
     };
 
     return constructor;
@@ -707,6 +711,9 @@ var Cmd = (function() {
     }
 
     constructor.prototype = {
+      toString: function() {
+        return this.cmd;
+      }
     };
 
     return constructor;
@@ -729,6 +736,16 @@ var Dict = (function() {
         },
         set: function(key, value) {
             this.map[key] = value;
+        },
+        forEach: function(aCallback) {
+          for (var key in this.map)
+            aCallback(key, this.map[key]);
+        },
+        toString: function() {
+          var keys = [];
+          for (var key in this.map)
+            keys.push(key);
+          return "Dict with " + keys.length + " keys: " + keys;
         }
     };
 
@@ -951,6 +968,7 @@ var Lexer = (function() {
                                 x = (x << 3) + (ch - '0');
                             }
                         }
+
                         str += String.fromCharCode(x);
                         break;
                     case '\r':
@@ -1072,10 +1090,11 @@ var Lexer = (function() {
                     stream.skip();
                     return new Cmd(">>");
                 }
+            case "{":
+            case "}":
+              return new Cmd(ch);
 	        // fall through
             case ')':
-            case '{':
-            case '}':
                 error("Illegal character");
                 return Error;
             }
@@ -1880,7 +1899,49 @@ var CanvasGraphics = (function() {
 
     constructor.prototype = {
         translateFont: function(fontDict, xref, resources) {
-            return "translated";
+            var descriptor = xref.fetch(fontDict.get("FontDescriptor"));
+            var fontName = descriptor.get("FontName").name;
+            fontName = fontName.replace("+", "_");
+
+            var font = Fonts[fontName];
+            if (!font) {
+                var fontFile = descriptor.get2("FontFile", "FontFile2");
+                fontFile = xref.fetchIfRef(fontFile);
+
+                // Generate the custom cmap of the font if needed
+                var encodingMap = {};
+                if (fontDict.has("Encoding")) {
+                  var encoding = xref.fetchIfRef(fontDict.get("Encoding"));
+                  if (IsDict(encoding)) {
+                      // Build an map between codes and glyphs
+                      var differences = encoding.get("Differences");
+                      var index = 0;
+                      for (var j = 0; j < differences.length; j++) {
+                          var data = differences[j];
+                          IsNum(data) ? index = data : encodingMap[index++] = data;
+                      }
+
+                      // Get the font charset
+                      var charset = descriptor.get("CharSet").split("/");
+                  } else if (IsName(encoding)) {
+                      var encoding = Encodings[encoding];
+                      var widths = xref.fetchIfRef(fontDict.get("Widths"));
+                      var firstchar = xref.fetchIfRef(fontDict.get("FirstChar"));
+
+                      var charset = [];
+                      for (var j = 0; j < widths.length; j++) {
+                          var index = widths[j];
+                          if (index)
+                              charset.push(encoding[j + firstchar]);
+                      }
+                  }
+              }
+
+              var fontBBox = descriptor.get("FontBBox");
+              var subtype = fontDict.get("Subtype").name;
+              new Font(fontName, fontFile, encodingMap, charset, fontBBox, subtype);
+          }
+          return Fonts[fontName];
         },
 
         beginDrawing: function(mediaBox) {
@@ -2117,16 +2178,25 @@ var CanvasGraphics = (function() {
             this.current.leading = leading;
         },
         setFont: function(fontRef, size) {
-            var fontRes = this.res.get("Font");
-            if (!fontRes)
-                return;
-            fontRes = this.xref.fetchIfRef(fontRes);
-            var font = fontRes.get(fontRef.name);
+            var font = this.res.get("Font");
+            if (!IsDict(font))
+              return;
+
+            font = font.get(fontRef.name);
+            font = this.xref.fetchIfRef(font);
             if (!font)
                 return;
+
+            var fontName = "";
+            var fontDescriptor = font.get("FontDescriptor");
+            if (fontDescriptor.num) {
+                var fontDescriptor = this.xref.fetchIfRef(fontDescriptor);
+                fontName = fontDescriptor.get("FontName").name.replace("+", "_");
+                Fonts.active = fontName;
+            }
+
             this.current.fontSize = size;
-            TODO("using hard-coded font for testing");
-            this.ctx.font = this.current.fontSize +'px "Nimbus Roman No9 L"';
+            this.ctx.font = this.current.fontSize +'px "' + fontName + '"';
         },
         setTextRenderingMode: function(mode) {
             TODO("text rendering mode");
@@ -2156,7 +2226,12 @@ var CanvasGraphics = (function() {
             this.ctx.scale(1, -1);
             this.ctx.transform.apply(this.ctx, this.current.textMatrix);
 
-            this.ctx.fillText(text, this.current.x, this.current.y);
+            // Replace characters code by glyphs code
+            var glyphs = [];
+            for (var i = 0; i < text.length; i++)
+              glyphs[i] = String.fromCharCode(Fonts.unicodeFromCode(text[i].charCodeAt(0)));
+
+            this.ctx.fillText(glyphs.join(""), this.current.x, this.current.y);
             this.current.x += this.ctx.measureText(text).width;
 
             this.ctx.restore();
diff --git a/test.css b/test.css
new file mode 100644
index 000000000..857eed101
--- /dev/null
+++ b/test.css
@@ -0,0 +1,35 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- /
+/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
+
+body {
+    margin: 6px;
+    padding: 0px;
+    background-color: #c0bdb7;
+}
+
+#controls {
+    position:fixed;
+    left: 0px;
+    top: 0px;
+    width: 100%;
+    padding: 7px;
+    border-bottom: 1px solid black;
+    background-color: rgb(242, 240, 238);
+}
+
+span#info {
+    float: right;
+    font: 14px sans-serif;
+    margin-right: 10px;
+}
+
+#viewer {
+    margin: auto;
+    border: 1px solid black;
+    width: 12.75in;
+    height: 16.5in;
+}
+
+#pageNumber {
+    text-align: right;
+}
diff --git a/test.html b/test.html
index 9cadf2e1f..458c50268 100644
--- a/test.html
+++ b/test.html
@@ -1,149 +1,35 @@
 <html>
-<head>
-  <title>Simple pdf.js page viewer</title>
-  <script type="text/javascript"
-          src="pdf.js"></script>
-  <style type"text/css">
-body {
-  margin: 6px;
-  padding: 0px;
-  background-color: #c0bdb7;
-}
-#controls {
-  border-bottom: 1px solid black;
-  position:fixed;
-  left: 0px; top: 0px;
-  width: 100%;
-  padding: 7px;
-  background-color: rgb(242, 240, 238);
-}
-span#info {
-  float: right;
-  font: 14px sans-serif;
-  margin-right: 10px;
-}
-#viewer {
-  margin: auto;
-  border: 1px solid black;
-  width: 8.5in;
-  height: 11in;
-}
-#pageNumber {
-  text-align: right;
-}
-  </style>
+    <head>
+        <title>Simple pdf.js page viewer</title>
+        <link rel="stylesheet" href="test.css"></link>
 
-<script type="text/javascript">
-function queryParams() {
-    var qs = window.location.search.substring(1);
-    var kvs = qs.split("&");
-    var params = { };
-    for (var i = 0; i < kvs.length; ++i) {
-        var kv = kvs[i].split("=");
-        params[unescape(kv[0])] = unescape(kv[1]);
-    }
-    return params;
-}
+        <script type="text/javascript" src="test.js"></script>
+        <script type="text/javascript" src="pdf.js"></script>
+        <script type="text/javascript" src="fonts.js"></script>
+        <script type="text/javascript" src="cffStandardStrings.js"></script>
+        <script type="text/javascript" src="Encodings.js"></script>
+        <script type="text/javascript" src="glyphlist.js"></script>
+  </head>
 
-var canvas, numPages, pageDisplay, pageNum;
-function load() {
-    canvas = document.getElementById("canvas");
-    canvas.mozOpaque = true;
-    pageDisplay = document.getElementById("pageNumber");
-    infoDisplay = document.getElementById("info");
-    pageNum = parseInt(queryParams().page) || 1;
-    fileName = queryParams().file || "compressed.tracemonkey-pldi-09.pdf";
-    open(fileName);
-}
-
-function open(url) {
-    document.title = url;
-    req = new XMLHttpRequest();
-    req.open("GET", url);
-    req.mozResponseType = req.responseType = "arraybuffer";
-    req.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200;
-    req.onreadystatechange = xhrstate;
-    req.send(null);
-}
-
-function xhrstate() {
-    if (req.readyState == 4 && req.status == req.expected) {
-        var data = req.mozResponseArrayBuffer ||
-                   req.mozResponse ||
-                   req.responseArrayBuffer ||
-                   req.response;
-        pdf = new PDFDoc(new Stream(data));
-        numPages = pdf.numPages;
-        document.getElementById("numPages").innerHTML = numPages.toString();
-        gotoPage(pageNum);
-    }
-}
-
-function displayPage(num) {
-    pageDisplay.value = num;
-
-    var t0 = Date.now();
-
-    var page = pdf.getPage(pageNum = num);
-
-    var t1 = Date.now();
-
-    var ctx = canvas.getContext("2d");
-    ctx.save();
-    ctx.fillStyle = "rgb(255, 255, 255)";
-    ctx.fillRect(0, 0, canvas.width, canvas.height);
-    ctx.restore();
-
-    var gfx = new CanvasGraphics(ctx);
-
-    // page.compile will collect all fonts for us, once we have loaded them
-    // we can trigger the actual page rendering with page.display
-    var fonts = [];
-    page.compile(gfx, fonts);
-
-    var t2 = Date.now();
-
-    // This should be called when font loading is complete
-    page.display(gfx);
-
-    var t3 = Date.now();
-
-    infoDisplay.innerHTML = "Time to load/compile/render: "+ (t1 - t0) + "/" + (t2 - t1) + "/" + (t3 - t2) + " ms";
-}
-
-function nextPage() {
-    if (pageNum < numPages)
-        ++pageNum;
-    displayPage(pageNum);
-}
-
-function prevPage() {
-    if (pageNum > 1)
-        --pageNum;
-    displayPage(pageNum);
-}
-function gotoPage(num) {
-    if (0 <= num && num <= numPages)
-        pageNum = num;
-    displayPage(pageNum);
-}
-  </script>
-</head>
-
-<body onload="load();">
-  <div id="controls">
-    <button onclick="prevPage();">Previous</button>
-    <button onclick="nextPage();">Next</button>
-    <input type="text" id="pageNumber" onchange="gotoPage(this.value);"
-           value="1" size="4"></input>
-    / <span id="numPages">--</span>
-    <span id="info"></span>
-  </div>
-  <div id="viewer">
-    <!-- Canvas dimensions must be specified in CSS pixels.  CSS pixels
-      -- are always 96 dpi.  These dimensions are 8.5x11in at 96dpi. -->
-    <canvas id="canvas" width="816" height="1056"></canvas>
-  </div>
-</body>
+  <body onload="load();">
+    <div id="controls">
+    <input type="file" style="float: right; margin: auto 32px;" onChange="load(this.value.toString());"></input>
+    <!-- This only opens supported PDFs from the source path...
+      -- Can we use JSONP to overcome the same-origin restrictions? -->
+      <button onclick="prevPage();">Previous</button>
+      <button onclick="nextPage();">Next</button>
+      <input type="text" id="pageNumber" onchange="gotoPage(this.value);"
+             value="1" size="4"></input>
+      <span id="numPages">--</span>
+      <span id="info"></span>
+    </div>
 
+    <div id="viewer">
+      <!-- Canvas dimensions must be specified in CSS pixels.  CSS pixels
+           are always 96 dpi.  816x1056 is 8.5x11in at 96dpi. -->
+      <!-- We're rendering here at 1.5x scale. -->
+      <canvas id="canvas" width="1224" height="1584"></canvas>
+    </div>
+  </body>
 </html>
+
diff --git a/test.js b/test.js
new file mode 100644
index 000000000..cbfd70c65
--- /dev/null
+++ b/test.js
@@ -0,0 +1,117 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- /
+/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
+
+var pdfDocument, canvas, pageDisplay, pageNum, pageInterval;
+function load(userInput) {
+    canvas = document.getElementById("canvas");
+    canvas.mozOpaque = true;
+    pageNum = parseInt(queryParams().page) || 1;
+    fileName = userInput;
+    if (!userInput) {
+      fileName = queryParams().file || "compressed.tracemonkey-pldi-09.pdf";
+    }
+    open(fileName);
+}
+
+function queryParams() {
+    var qs = window.location.search.substring(1);
+    var kvs = qs.split("&");
+    var params = { };
+    for (var i = 0; i < kvs.length; ++i) {
+        var kv = kvs[i].split("=");
+        params[unescape(kv[0])] = unescape(kv[1]);
+    }
+    return params;
+}
+
+function open(url) {
+    document.title = url;
+    req = new XMLHttpRequest();
+    req.open("GET", url);
+    req.mozResponseType = req.responseType = "arraybuffer";
+    req.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200;
+    req.onreadystatechange = function() {
+      if (req.readyState == 4 && req.status == req.expected) {
+        var data = req.mozResponseArrayBuffer || req.mozResponse ||
+                   req.responseArrayBuffer || req.response;
+        pdfDocument = new PDFDoc(new Stream(data));
+        numPages = pdfDocument.numPages;
+        document.getElementById("numPages").innerHTML = numPages.toString();
+        goToPage(pageNum);
+      }
+    };
+    req.send(null);
+}
+
+function gotoPage(num) {
+    if (0 <= num && num <= numPages)
+        pageNum = num;
+    displayPage(pageNum);
+}
+
+function displayPage(num) {
+    if (pageNum != num)
+      window.clearTimeout(pageInterval);
+
+    document.getElementById("pageNumber").value = num;
+
+    var t0 = Date.now();
+
+    var page = pdfDocument.getPage(pageNum = num);
+
+    var t1 = Date.now();
+    var ctx = canvas.getContext("2d");
+    ctx.save();
+    ctx.fillStyle = "rgb(255, 255, 255)";
+    ctx.fillRect(0, 0, canvas.width, canvas.height);
+    ctx.restore();
+
+    var gfx = new CanvasGraphics(ctx);
+
+    // page.compile will collect all fonts for us, once we have loaded them
+    // we can trigger the actual page rendering with page.display
+    var fonts = [];
+    page.compile(gfx, fonts);
+    var t2 = Date.now();
+
+    var interval = 0;
+    for (var i = 0; i < fonts.length; i++) {
+      if (fonts[i].loading) {
+        interval = 10;
+        break;
+      }
+    };
+
+    // FIXME This need to be replaced by an event
+    pageInterval = setInterval(function() {
+        for (var i = 0; i < fonts.length; i++) {
+            if (fonts[i].loading)
+                return;
+        }
+        var t3 = Date.now();
+
+        clearInterval(pageInterval);
+        page.display(gfx);
+
+        var t4 = Date.now();
+
+        var infoDisplay = document.getElementById("info");
+        infoDisplay.innerHTML = "Time to load/compile/fonts/render: "+ (t1 - t0) + "/" + (t2 - t1) + "/" + (t3 - t2) + "/" + (t4 - t3) + " ms";
+    }, interval);
+}
+
+function nextPage() {
+    if (pageNum < pdfDocument.numPages)
+      displayPage(++pageNum);
+}
+
+function prevPage() {
+    if (pageNum > 1)
+      displayPage(--pageNum);
+}
+
+function goToPage(num) {
+  if (0 <= num && num <= numPages)
+    displayPage(pageNum = num);
+}
+