From c76e2c511421010a6e6dcc86a278f6afe71c1cfc Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 26 May 2011 16:02:52 +0200 Subject: [PATCH 01/77] Separate js and css from the test.html file --- test.css | 35 ++++++++++++++ test.html | 141 ++++++++---------------------------------------------- test.js | 66 +++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 120 deletions(-) create mode 100644 test.css create mode 100644 test.js diff --git a/test.css b/test.css new file mode 100644 index 000000000..0a3449ae9 --- /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: 8.5in; + height: 11in; +} + +#pageNumber { + text-align: right; +} diff --git a/test.html b/test.html index 10a35e163..f14533add 100644 --- a/test.html +++ b/test.html @@ -1,125 +1,26 @@ - - Simple pdf.js page viewer - - + + Simple pdf.js page viewer + - + + -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; - displayPage(1); - } -} - -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.display(gfx); - - var t2 = Date.now(); - - infoDisplay.innerHTML = "Time to render: "+ (t1 - t0) + "/" + (t2 - t1) + " 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); -} - - - - -
- - - - -
-
- - -
- + +
+ + + + +
+
+ + +
+ + diff --git a/test.js b/test.js new file mode 100644 index 000000000..ef586cd34 --- /dev/null +++ b/test.js @@ -0,0 +1,66 @@ +/* -*- 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; +function load() { + canvas = document.getElementById("canvas"); + canvas.mozOpaque = true; + open("uncompressed.tracemonkey-pldi-09.pdf"); +} + +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)); + displayPage(1); + } + }; + req.send(null); +} + +function displayPage(num) { + 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.display(gfx); + + var t2 = Date.now(); + + var infoDisplay = document.getElementById("info"); + infoDisplay.innerHTML = "Time to render: "+ (t1 - t0) + "/" + (t2 - t1) + " ms"; +} + +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); +} + From fe11af4b57cbe77a6b70b09db782d54c0892d93d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 31 May 2011 20:22:05 +0200 Subject: [PATCH 02/77] Add a the beggining of a Type1 font reader --- PDFFont.js | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++ pdf.js | 36 ++++++++- test.html | 1 + 3 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 PDFFont.js diff --git a/PDFFont.js b/PDFFont.js new file mode 100644 index 000000000..8328c8a59 --- /dev/null +++ b/PDFFont.js @@ -0,0 +1,226 @@ + + +var Type1Parser = function(aLexer) { + var lexer = aLexer; + + + /* + * The operand stack holds arbitrary PostScript objects that are the operands + * and results of PostScript operators being executed. The interpreter pushes + * objects on the operand stack when it encounters them as literal data in a + * program being executed. When an operator requires one or more operands, it + * obtains them by popping them off the top of the operand stack. When an + * operator returns one or more results, it does so by pushing them on the + * operand stack. + */ + var operandStack = []; + + + /* + * The dictionary stack holds only dictionary objects. The current set of + * dictionaries on the dictionary stack defines the environment for all + * implicit name searches, such as those that occur when the interpreter + * encounters an executable name. The role of the dictionary stack is + * introduced in Section 3.3, “Data Types and Objects,” and is further + * explained in Section 3.5, “Execution.” of the PostScript Language + * Reference. + */ + var systemDict = new Dict(), + globalDict = new Dict(), + userDict = new Dict(); + + + var dictionaryStack = { + __innerStack__: [systemDict, globalDict], + + push: function(aDictionary) { + this.__innerStack__.push(aDictionary); + }, + + pop: function() { + if (this.__innerStack__.length == 2) + return null; + + return this.__innerStack__.pop(); + }, + + peek: function() { + return this.__innerStack__[this.__innerStack__.length - 1]; + } + } + var currentDict = dictionaryStack.peek(); + + + /* + * The execution stack holds executable objects (mainly procedures and files) + * that are in intermediate stages of execution. At any point in the + * execution of a PostScript program, this stack represents the program’s + * call stack. Whenever the interpreter suspends execution of an object to + * execute some other object, it pushes the new object on the execution + * stack. When the interpreter finishes executing an object, it pops that + * object off the execution stack and resumes executing the suspended object + * beneath it. + */ + var isExecutionStack = false; + var executionStack = []; + + /* Stub to inhibit the logs */ + + this.getObj = function() { + var obj = lexer.getObj(); + if (isExecutionStack && !IsCmd(obj, "}") && !IsCmd(obj, "]")) { + executionStack.push(obj); + this.getObj(); + } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { + log("Value: " + obj); + operandStack.push(obj); + this.getObj(); + } else if (IsCmd(obj, "dup") || IsCmd(obj, "readonly") || + IsCmd(obj, "currentdict") || IsCmd(obj, "currentfile")) { + // Do nothing for the moment + this.getObj(); + } else if (IsName(obj)) { + log("Name: " + obj.name); + operandStack.push(obj.name); + this.getObj(); + } else if (IsCmd(obj, "dict")) { + log("Dict: " + obj); + + // XXX handling of dictionary is wrong here + var size = operandStack.pop(); + var name = operandStack.pop(); + if (!name) { + log ("Creating the global dict"); + currentDict = dictionaryStack.peek(); + } else { + var dict = new Dict(); + log("Assign name: " + name + " for the dictionary"); + currentDict.set(name, dict); + dictionaryStack.push(dict); + } + + this.getObj(); + } else if (IsCmd(obj, "begin")) { + log("begin a dictionary"); + currentDict = dictionaryStack.peek(); + this.getObj(); + } else if (IsCmd(obj, "end")) { + log("Ending a dictionary"); + dictionaryStack.pop(); + currentDict = dictionaryStack.peek(); + this.getObj(); + } else if (IsCmd(obj, "def")) { + if (executionStack.length) { + var value = []; + while (executionStack.length) + value.push(executionStack.shift()); + } else { + var value = operandStack.pop(); + } + + var key = operandStack.pop(); + // XXX this happen because of a bad way to handle dictionary + if (key) { + log("def: " + key + " = " + value); + currentDict.set(key, value); + } + this.getObj(); + } else if (IsCmd(obj, "{")) { + log("Start Proc: " + obj); + executionStack = []; + isExecutionStack = true; + this.getObj(); + } else if (IsCmd(obj, "}")) { + log("End Proc: " + obj); + isExecutionStack = false; + this.getObj(); + } else if (IsCmd(obj, "[")) { + isExecutionStack = true; + executionStack = []; + this.getObj(); + log("Start array: " + obj); + } else if (IsCmd(obj, "]")) { + log("End array: " + obj); + isExecutionStack = false; + this.getObj(); + } else if (IsCmd(obj, "eexec")) { + return; // end of the ASCII header + } else { + log("Getting an unknow token, adding it to the stack just in case"); + log(obj); + operandStack.push(obj); + this.getObj(); + } + return currentDict; + } +}; + +var hack = false; + +var Type1Font = function(aFontName, aFontFile) { + // All type1 font program should begin with the comment %! + var validHeader = aFontFile.getByte() == 0x25 && aFontFile.getByte() == 0x21; + if (!validHeader) + error("Invalid file header"); + + var programType = "PS-AdobeFont"; + for (var i = 0; i< programType.length; i++) + aFontFile.getChar(); + + // Ignore the '-' separator + aFontFile.getChar(); + + var version = parseFloat(aFontFile.getChar() + aFontFile.getChar() + aFontFile.getChar()); + + if (!hack) { + log(aFontName); + log("Version is: " + version); + + var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); + this.parser = new Type1Parser(new Lexer(ASCIIStream)); + + var fontDictionary = this.parser.getObj(); + log(fontDictionary + "\t" + + "fontInfo: " + fontDictionary.get("FontInfo") + "\t" + + "charStrings: " + fontDictionary.get("charStrings")); + + var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); + function decrypt(aBinaryStream, aKey) { + var c1 = 52845, c2 = 22719; + var R = aKey; + + var streamSize = aBinaryStream.length; + var decryptedString = []; + + var value = null; + for (var i = 0; i < streamSize; i++) { + value = aBinaryStream.getByte(); + decryptedString[i] = String.fromCharCode(value ^ (R >> 8)); + R = ((value + R) * c1 + c2) & ((1 << 16) - 1); + } + return decryptedString.slice(4); + } + + var eexecString = decrypt(binaryStream, 55665).join(""); + log(eexecString); + + TODO("decrypt charStrings data with the key 4330"); + hack = true; + } + + + this.info = {}; + this.name = aFontName; + this.encoding = []; + this.paintType = 0; + this.fontType = 0; + this.fontMatrix = []; + this.fontBBox = []; + this.uniqueID = 0; + this.metrics = {}; + this.strokeWidth = 0.0; + this.private = {}; + this.charStrings = {} + this.FID = 0; +}; + diff --git a/pdf.js b/pdf.js index 0628cfe32..8caac0362 100644 --- a/pdf.js +++ b/pdf.js @@ -1032,6 +1032,12 @@ var Dict = (function() { }, set: function(key, value) { this.map[key] = value; + }, + toString: function() { + var keys = []; + for (var key in this.map) + keys.push(key); + return "Dict with " + keys.length + " keys: " + keys; } }; @@ -1360,10 +1366,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; } @@ -2258,11 +2265,34 @@ var CanvasGraphics = (function() { }, setFont: function(fontRef, size) { var font = this.res.get("Font").get(fontRef.name); + font = this.xref.fetchIfRef(font); if (!font) return; + + var fontName = "Nimbus Roman No9 L"; + var subtype = font.get("Subtype").name; + switch (subtype) { + case "Type1": + var fontDescriptor = font.get("FontDescriptor"); + if (fontDescriptor.num) { + var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); + var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); + font = new Type1Font(fontDescriptor.get("FontName").name, fontFile); + } + break; + + case "Type3": + TODO("support Type3 font"); + break; + + default: + error("Unsupported font type: " + subtype); + break; + } + 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 + '"'; }, moveText: function (x, y) { this.current.x = this.current.lineX += x; diff --git a/test.html b/test.html index f14533add..ac568473a 100644 --- a/test.html +++ b/test.html @@ -5,6 +5,7 @@ + From 3064305d91451d3e04d5784a29ecbbb33bfc25a7 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 1 Jun 2011 11:52:10 +0200 Subject: [PATCH 03/77] Prepare the way to decode Type1 charStrings --- PDFFont.js | 232 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 133 insertions(+), 99 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 8328c8a59..534817c94 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,10 +1,39 @@ +var Type1Parser = function(aAsciiStream, aBinaryStream) { + var lexer = new Lexer(aAsciiStream); -var Type1Parser = function(aLexer) { - var lexer = aLexer; + // 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) { + var r = aKey, c1 = 52845, c2 = 22719; + + var decryptedString = []; + var value = null; + + var count = aStream.length; + for (var i = 0; i < count; i++) { + value = aStream.getByte(); + decryptedString[i] = String.fromCharCode(value ^ (r >> 8)); + r = ((value + r) * c1 + c2) & ((1 << 16) - 1); + } + return decryptedString.slice(aDiscardNumber); + } + + /* * The operand stack holds arbitrary PostScript objects that are the operands * and results of PostScript operators being executed. The interpreter pushes * objects on the operand stack when it encounters them as literal data in a @@ -13,8 +42,28 @@ var Type1Parser = function(aLexer) { * operator returns one or more results, it does so by pushing them on the * operand stack. */ - var operandStack = []; + var operandStack = { + __innerStack__: [], + push: function(aOperand) { + this.__innerStack__.push(aOperand); + }, + + pop: function() { + return this.__innerStack__.pop(); + }, + + peek: function() { + return this.__innerStack__[this.__innerStack__.length - 1]; + }, + + get length() { + return this.__innerStack__.length; + } + }; + + // Flag indicating if the topmost operand of the operandStack is an array + var operandIsArray = false; /* * The dictionary stack holds only dictionary objects. The current set of @@ -28,7 +77,6 @@ var Type1Parser = function(aLexer) { var systemDict = new Dict(), globalDict = new Dict(), userDict = new Dict(); - var dictionaryStack = { __innerStack__: [systemDict, globalDict], @@ -46,10 +94,12 @@ var Type1Parser = function(aLexer) { peek: function() { return this.__innerStack__[this.__innerStack__.length - 1]; + }, + + get length() { + return this.__innerStack__.length; } } - var currentDict = dictionaryStack.peek(); - /* * The execution stack holds executable objects (mainly procedures and files) @@ -61,150 +111,134 @@ var Type1Parser = function(aLexer) { * object off the execution stack and resumes executing the suspended object * beneath it. */ - var isExecutionStack = false; var executionStack = []; - /* Stub to inhibit the logs */ - this.getObj = function() { var obj = lexer.getObj(); - if (isExecutionStack && !IsCmd(obj, "}") && !IsCmd(obj, "]")) { - executionStack.push(obj); + + if (operandIsArray && !IsCmd(obj, "}") && !IsCmd(obj, "]")) { + operandStack.peek().push(obj); + this.getObj(); + } else if (IsCmd(obj, "{") || IsCmd(obj, "[")) { + dump("Start Array: " + obj); + operandStack.push([]); + operandIsArray = true; + this.getObj(); + } else if (IsCmd(obj, "}") || IsCmd(obj, "]")) { + dump("End Array: " + obj); + operandIsArray = false; this.getObj(); } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { - log("Value: " + obj); + dump("Value: " + obj); operandStack.push(obj); this.getObj(); - } else if (IsCmd(obj, "dup") || IsCmd(obj, "readonly") || - IsCmd(obj, "currentdict") || IsCmd(obj, "currentfile")) { + } else if (IsCmd(obj, "dup")) { + dump("Duplicate"); + operandStack.push(operandStack.peek()); + this.getObj(); + } else if (IsCmd(obj, "currentdict")) { + dump("currentdict"); + operandStack.push(dictionaryStack.peek()); + this.getObj(); + } else if (IsCmd(obj, "systemdict")) { + dump("systemdict"); + operandStack.push(systemDict); + this.getObj(); + } else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") || + IsCmd(obj, "currentfile")) { // Do nothing for the moment this.getObj(); } else if (IsName(obj)) { - log("Name: " + obj.name); + dump("Name: " + obj.name); operandStack.push(obj.name); this.getObj(); } else if (IsCmd(obj, "dict")) { - log("Dict: " + obj); - - // XXX handling of dictionary is wrong here + dump("Dict: " + obj); var size = operandStack.pop(); - var name = operandStack.pop(); - if (!name) { - log ("Creating the global dict"); - currentDict = dictionaryStack.peek(); - } else { - var dict = new Dict(); - log("Assign name: " + name + " for the dictionary"); - currentDict.set(name, dict); - dictionaryStack.push(dict); - } - + var dict = new Dict(size); + operandStack.push(dict); this.getObj(); } else if (IsCmd(obj, "begin")) { - log("begin a dictionary"); - currentDict = dictionaryStack.peek(); + dump("begin a dictionary"); + dictionaryStack.push(operandStack.pop()); this.getObj(); } else if (IsCmd(obj, "end")) { - log("Ending a dictionary"); + dump("Ending a dictionary"); dictionaryStack.pop(); - currentDict = dictionaryStack.peek(); this.getObj(); } else if (IsCmd(obj, "def")) { - if (executionStack.length) { - var value = []; - while (executionStack.length) - value.push(executionStack.shift()); - } else { - var value = operandStack.pop(); - } - + var value = operandStack.pop(); var key = operandStack.pop(); - // XXX this happen because of a bad way to handle dictionary - if (key) { - log("def: " + key + " = " + value); - currentDict.set(key, value); - } - this.getObj(); - } else if (IsCmd(obj, "{")) { - log("Start Proc: " + obj); - executionStack = []; - isExecutionStack = true; - this.getObj(); - } else if (IsCmd(obj, "}")) { - log("End Proc: " + obj); - isExecutionStack = false; - this.getObj(); - } else if (IsCmd(obj, "[")) { - isExecutionStack = true; - executionStack = []; - this.getObj(); - log("Start array: " + obj); - } else if (IsCmd(obj, "]")) { - log("End array: " + obj); - isExecutionStack = false; + dump("def: " + key + " = " + value); + dictionaryStack.peek().set(key, value); this.getObj(); } else if (IsCmd(obj, "eexec")) { - return; // end of the ASCII header + // All the first segment data has been read, decrypt the second segment + // and start interpreting it in order to decode it + var eexecString = decrypt(aBinaryStream, kEexecEncryptionKey, 4).join(""); + lexer = new Lexer(new StringStream(eexecString)); + + this.getObj(); + } else if (IsCmd(obj, "known")) { + dump("known"); + var name = operandStack.pop(); + var dict = operandStack.pop(); + // returns dict.hasKey(name); + + this.getObj(); + } else if (IsCmd(obj, "RD")) { + dump("RD"); + var size = operandStack.pop(); + var key = operandStack.pop(); + + var stream = lexer.stream.makeSubStream(lexer.stream.pos, size); + var charString = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); + + // XXX do we want to store that on the top dictionary or somewhere else + dictionaryStack.peek().set(key, new StringStream(charString)); + log (new StringStream(charString)); + this.getObj(); + } else if (IsCmd(obj, "LenIV")) { + error("LenIV: argh! we need to modify the length of discard characters for charStrings"); } else { - log("Getting an unknow token, adding it to the stack just in case"); - log(obj); + dump("Getting an unknow token, adding it to the stack just in case"); + dump(obj); operandStack.push(obj); this.getObj(); } - return currentDict; + + return operandStack.peek(); } }; var hack = false; var Type1Font = function(aFontName, aFontFile) { - // All type1 font program should begin with the comment %! + // All Type1 font program should begin with the comment %! var validHeader = aFontFile.getByte() == 0x25 && aFontFile.getByte() == 0x21; if (!validHeader) error("Invalid file header"); var programType = "PS-AdobeFont"; - for (var i = 0; i< programType.length; i++) + for (var i = 0; i < programType.length; i++) aFontFile.getChar(); // Ignore the '-' separator aFontFile.getChar(); var version = parseFloat(aFontFile.getChar() + aFontFile.getChar() + aFontFile.getChar()); - + if (!hack) { log(aFontName); log("Version is: " + version); var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); - this.parser = new Type1Parser(new Lexer(ASCIIStream)); + var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); + + this.parser = new Type1Parser(ASCIIStream, binaryStream); var fontDictionary = this.parser.getObj(); - log(fontDictionary + "\t" + - "fontInfo: " + fontDictionary.get("FontInfo") + "\t" + - "charStrings: " + fontDictionary.get("charStrings")); - - var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); - function decrypt(aBinaryStream, aKey) { - var c1 = 52845, c2 = 22719; - var R = aKey; - - var streamSize = aBinaryStream.length; - var decryptedString = []; - - var value = null; - for (var i = 0; i < streamSize; i++) { - value = aBinaryStream.getByte(); - decryptedString[i] = String.fromCharCode(value ^ (R >> 8)); - R = ((value + R) * c1 + c2) & ((1 << 16) - 1); - } - return decryptedString.slice(4); - } - - var eexecString = decrypt(binaryStream, 55665).join(""); - log(eexecString); - - TODO("decrypt charStrings data with the key 4330"); + log(fontDictionary + "\t" + "fontInfo: " + fontDictionary.get("FontInfo")); hack = true; } From e936f305d73cdb19c960a15c2a7a6cb05314b1ec Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 1 Jun 2011 16:50:32 +0200 Subject: [PATCH 04/77] Decode charStrings and stop the interpreter on every unknow token --- PDFFont.js | 166 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 138 insertions(+), 28 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 534817c94..e8987dc36 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -20,10 +20,9 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { function decrypt(aStream, aKey, aDiscardNumber) { var r = aKey, c1 = 52845, c2 = 22719; - var decryptedString = []; - var value = null; + var value = ""; var count = aStream.length; for (var i = 0; i < count; i++) { value = aStream.getByte(); @@ -33,6 +32,108 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { 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. + */ + function decodeCharString(aStream) { + var charString = []; + var cmd = { + "1": "hstem", + "3": "vstem", + "4": "vmoveto", + "5": "rlineto", + "6": "hlineto", + "7": "vlineto", + "8": "rrcurveto", + "9": "closepath", + "10": "callsubr", + "11": "return", + "12": { + "0": "dotsection", + "1": "vstem3", + "3": "hstem3", + "6": "seac", + "7": "sbw", + "12": "div", + "16": "callothersubr", + "17": "pop", + "33": "setcurrentpoint" + }, + "13": "hsbw", + "14": "endchar", + "21": "rmoveto", + "22": "hmoveto", + "30": "vhcurveto", + "31": "hcurveto" + } + + var value = ""; + var count = aStream.length; + for (var i = 0; i < count; i++) { + value = aStream.getByte(); + + if (value < 0) { + continue; + } else if (value < 32) { + if (value == 12) { + value = cmd["12"][aStream.getByte()]; + count++; + } else { + value = cmd[value]; + } + } else if (value <= 246) { + value = parseInt(value) - 139; + } else if (value <= 250) { + value = ((value - 247) * 256) + parseInt(aStream.getByte()) + 108; + count++; + } else if (value <= 254) { + value = -((value - 251) * 256) - parseInt(aStream.getByte()) - 108; + count++; + } else { + error("Two complement signed integers are ignored for the moment"); + } + + charString.push(value); + } + + return charString; + } + /* * The operand stack holds arbitrary PostScript objects that are the operands * and results of PostScript operators being executed. The interpreter pushes @@ -63,7 +164,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }; // Flag indicating if the topmost operand of the operandStack is an array - var operandIsArray = false; + var operandIsArray = 0; /* * The dictionary stack holds only dictionary objects. The current set of @@ -113,23 +214,31 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { */ var executionStack = []; + + /* + * Parse a font file from the first segment to the last assuming the eexec + * block is binary data. + * + * The method thrown an error if it encounters an unknown token. + */ this.getObj = function() { var obj = lexer.getObj(); - if (operandIsArray && !IsCmd(obj, "}") && !IsCmd(obj, "]")) { + if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") && + !IsCmd(obj, "}") && !IsCmd(obj, "]")) { operandStack.peek().push(obj); this.getObj(); } else if (IsCmd(obj, "{") || IsCmd(obj, "[")) { dump("Start Array: " + obj); operandStack.push([]); - operandIsArray = true; + operandIsArray++; this.getObj(); } else if (IsCmd(obj, "}") || IsCmd(obj, "]")) { dump("End Array: " + obj); - operandIsArray = false; + operandIsArray--; this.getObj(); } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { - dump("Value: " + obj); + //dump("Value: " + obj); operandStack.push(obj); this.getObj(); } else if (IsCmd(obj, "dup")) { @@ -145,11 +254,11 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { operandStack.push(systemDict); this.getObj(); } else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") || - IsCmd(obj, "currentfile")) { + IsCmd(obj, "currentfile") || IsCmd(obj, "NP")) { // Do nothing for the moment this.getObj(); } else if (IsName(obj)) { - dump("Name: " + obj.name); + //dump("Name: " + obj.name); operandStack.push(obj.name); this.getObj(); } else if (IsCmd(obj, "dict")) { @@ -191,20 +300,32 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var size = operandStack.pop(); var key = operandStack.pop(); - var stream = lexer.stream.makeSubStream(lexer.stream.pos, size); + // Add '1' because of the space separator, this is dirty + var stream = lexer.stream.makeSubStream(lexer.stream.pos + 1, size); + lexer.stream.skip(size + 1); + var charString = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); + var charStream = new StringStream(charString); // XXX do we want to store that on the top dictionary or somewhere else - dictionaryStack.peek().set(key, new StringStream(charString)); - log (new StringStream(charString)); + dictionaryStack.peek().set(key, charStream); + + var decodedCharString = decodeCharString(charStream); + log(decodedCharString); + this.getObj(); } else if (IsCmd(obj, "LenIV")) { error("LenIV: argh! we need to modify the length of discard characters for charStrings"); - } else { - dump("Getting an unknow token, adding it to the stack just in case"); - dump(obj); - operandStack.push(obj); + } else if (IsCmd(obj, "closefile")) { + // End of binary data; + } else if (IsCmd(obj, "StandardEncoding")) { + // For some reason the value is considered as a command, maybe it is + // because of the uppercae 'S' + operandStack.push(obj.cmd); this.getObj(); + } else { + dump(obj); + error("Unknow token while parsing font"); } return operandStack.peek(); @@ -215,22 +336,11 @@ var hack = false; var Type1Font = function(aFontName, aFontFile) { // All Type1 font program should begin with the comment %! - var validHeader = aFontFile.getByte() == 0x25 && aFontFile.getByte() == 0x21; - if (!validHeader) + if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); - var programType = "PS-AdobeFont"; - for (var i = 0; i < programType.length; i++) - aFontFile.getChar(); - - // Ignore the '-' separator - aFontFile.getChar(); - - var version = parseFloat(aFontFile.getChar() + aFontFile.getChar() + aFontFile.getChar()); - if (!hack) { log(aFontName); - log("Version is: " + version); var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); From e739bcc5154891cec31340121d1cdd4c12ac03a5 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 1 Jun 2011 20:40:25 +0200 Subject: [PATCH 05/77] Starts playing with the execution stack --- PDFFont.js | 148 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 14 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index e8987dc36..923a857fb 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -155,9 +155,19 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }, peek: function() { + if (!this.length) + return null; return this.__innerStack__[this.__innerStack__.length - 1]; }, + toString: function() { + log("=== Start Dumping operandStack ==="); + var str = []; + for (var i = 0; i < this.__innerStack__.length; i++) + log(this.__innerStack__[i]); + log("=== End Dumping operandStack ==="); + }, + get length() { return this.__innerStack__.length; } @@ -194,9 +204,15 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }, peek: function() { + if (!this.length) + return null; return this.__innerStack__[this.__innerStack__.length - 1]; }, + get: function(aIndex) { + return this.__innerStack__[aIndex]; + }, + get length() { return this.__innerStack__.length; } @@ -212,7 +228,42 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * object off the execution stack and resumes executing the suspended object * beneath it. */ - var executionStack = []; + var executionStack = { + __innerStack__: [], + + push: function(aProcedure) { + this.__innerStack__.push(aProcedure); + }, + + pop: function() { + return this.__innerStack__.pop(); + }, + + peek: function() { + if (!this.length) + return null; + return this.__innerStack__[this.__innerStack__.length - 1]; + }, + + get: function(aIndex) { + return this.__innerStack__[aIndex]; + }, + + get length() { + return this.__innerStack__.length; + } + } + + function nextInStack() { + var currentProcedure = executionStack.peek(); + if (currentProcedure) { + var command = currentProcedure.shift(); + if (!currentProcedure.length) + executionStack.pop(); + } + + return lexer.getObj(); + } /* @@ -222,29 +273,65 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * The method thrown an error if it encounters an unknown token. */ this.getObj = function() { - var obj = lexer.getObj(); + var obj = nextInStack(); if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") && !IsCmd(obj, "}") && !IsCmd(obj, "]")) { + dump("Adding: " + obj); operandStack.peek().push(obj); this.getObj(); } else if (IsCmd(obj, "{") || IsCmd(obj, "[")) { - dump("Start Array: " + obj); - operandStack.push([]); + dump("Start" + (obj.cmd == "{" ? " Executable " : " ") + "Array"); + operandIsArray ? operandStack.peek().push([]) : operandStack.push([]); operandIsArray++; this.getObj(); } else if (IsCmd(obj, "}") || IsCmd(obj, "]")) { - dump("End Array: " + obj); + dump("End" + (obj.cmd == "}" ? " Executable " : " ") + "Array"); operandIsArray--; this.getObj(); + } else if (IsCmd(obj, "if")) { + log("if"); + var procedure = operandStack.pop(); + var bool = operandStack.pop(); + if (!IsBool(bool)) { + executionStack.push(bool); + log("....."); + this.getObj(); + } + log(bool); + if (bool) + executionStack.push(procedure); + + this.getObj(); + } else if (IsCmd(obj, "ifelse")) { + log("ifelse"); + var procedure1 = operandStack.pop(); + var procedure2 = operandStack.pop(); + var bool = !!operandStack.pop(); + operandStack.push(bool ? procedure1 : procedure2); + this.getObj(); } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { - //dump("Value: " + obj); + dump("Value: " + obj); operandStack.push(obj); this.getObj(); } else if (IsCmd(obj, "dup")) { dump("Duplicate"); operandStack.push(operandStack.peek()); this.getObj(); + } else if (IsCmd(obj, "put") || IsCmd(obj, "NP")) { + operandStack.toString(); + + var data = operandStack.pop(); + var indexOrKey = operandStack.pop(); + var object = operandStack.pop(); + log(object); + log("put " + data + " in " + obj + "[" + indexOrKey + "]"); + + if (object.set) + object.set(indexOrKey, data); + else + object[indexOrKey] = data; + this.getObj(); } else if (IsCmd(obj, "currentdict")) { dump("currentdict"); operandStack.push(dictionaryStack.peek()); @@ -254,13 +341,18 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { operandStack.push(systemDict); this.getObj(); } else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") || - IsCmd(obj, "currentfile") || IsCmd(obj, "NP")) { + IsCmd(obj, "noaccess") || IsCmd(obj, "currentfile")) { // Do nothing for the moment this.getObj(); } else if (IsName(obj)) { //dump("Name: " + obj.name); operandStack.push(obj.name); this.getObj(); + } else if (IsCmd(obj, "array")) { + var size = operandStack.pop(); + var array = new Array(size); + operandStack.push(array); + this.getObj(); } else if (IsCmd(obj, "dict")) { dump("Dict: " + obj); var size = operandStack.pop(); @@ -275,10 +367,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { dump("Ending a dictionary"); dictionaryStack.pop(); this.getObj(); - } else if (IsCmd(obj, "def")) { + } else if (IsCmd(obj, "def") || IsCmd(obj, "ND")) { var value = operandStack.pop(); var key = operandStack.pop(); - dump("def: " + key + " = " + value); + log("def: " + key + " = " + value); dictionaryStack.peek().set(key, value); this.getObj(); } else if (IsCmd(obj, "eexec")) { @@ -292,8 +384,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { dump("known"); var name = operandStack.pop(); var dict = operandStack.pop(); - // returns dict.hasKey(name); - + operandStack.push(!!dict.get(name)); this.getObj(); } else if (IsCmd(obj, "RD")) { dump("RD"); @@ -311,21 +402,50 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { dictionaryStack.peek().set(key, charStream); var decodedCharString = decodeCharString(charStream); - log(decodedCharString); + dump(decodedCharString); this.getObj(); } else if (IsCmd(obj, "LenIV")) { error("LenIV: argh! we need to modify the length of discard characters for charStrings"); } else if (IsCmd(obj, "closefile")) { // End of binary data; + } else if (IsCmd(obj, "index")) { + var operands = []; + var size = operandStack.pop(); + for (var i = 0; i < size; i++) + operands.push(operandStack.pop()); + + var newOperand = operandStack.peek(); + + for (var i = 0; i < operands.length; i++) + operandStack.push(operands.pop()); + + operandStack.push(newOperand); + this.getObj(); } else if (IsCmd(obj, "StandardEncoding")) { // For some reason the value is considered as a command, maybe it is // because of the uppercae 'S' operandStack.push(obj.cmd); this.getObj(); } else { - dump(obj); - error("Unknow token while parsing font"); + var command = null; + if (IsCmd(obj)) { + for (var i = 0; i < dictionaryStack.length; i++) { + command = dictionaryStack.get(i).get(obj.cmd); + if (command) + break; + } + } + + if (command) { + // XXX add the command to the execution stack + this.getObj(); + } else { + log("operandStack: " + operandStack); + log("dictionaryStack: " + dictionaryStack); + dump(obj); + error("Unknow token while parsing font"); + } } return operandStack.peek(); From e302bd93eeaafc693c7e4ac9aa994cf7276953e0 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 3 Jun 2011 17:48:32 +0200 Subject: [PATCH 06/77] Add the necessary bits to handle Arrays, Procedure and a bigger set of instructions for Type1 --- PDFFont.js | 437 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 269 insertions(+), 168 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 923a857fb..00d9bd517 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,9 +1,11 @@ +var Font = new Dict(); + var Type1Parser = function(aAsciiStream, aBinaryStream) { var lexer = new Lexer(aAsciiStream); // Turn on this flag for additional debugging logs - var debug = false; + var debug = true; var dump = function(aData) { if (debug) @@ -106,7 +108,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var count = aStream.length; for (var i = 0; i < count; i++) { value = aStream.getByte(); - + if (value < 0) { continue; } else if (value < 32) { @@ -130,8 +132,8 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { charString.push(value); } - - return charString; + + return charString; } /* @@ -190,7 +192,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { userDict = new Dict(); var dictionaryStack = { - __innerStack__: [systemDict, globalDict], + __innerStack__: [systemDict, globalDict, userDict], push: function(aDictionary) { this.__innerStack__.push(aDictionary); @@ -216,7 +218,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { get length() { return this.__innerStack__.length; } - } + }; /* * The execution stack holds executable objects (mainly procedures and files) @@ -252,7 +254,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { get length() { return this.__innerStack__.length; } - } + }; function nextInStack() { var currentProcedure = executionStack.peek(); @@ -260,195 +262,295 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var command = currentProcedure.shift(); if (!currentProcedure.length) executionStack.pop(); + return command; } return lexer.getObj(); - } + }; + var self = this; + function parseNext() { + setTimeout(function() { + self.getObj(); + }, 0); + }; /* * Parse a font file from the first segment to the last assuming the eexec * block is binary data. - * + * * The method thrown an error if it encounters an unknown token. */ this.getObj = function() { var obj = nextInStack(); + if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") && + !IsCmd(obj, "]") && !IsCmd(obj, "}")) { + dump("Adding an object: " + obj +" to array " + operandIsArray); + var currentArray = operandStack.peek(); + for (var i = 1; i < operandIsArray; i++) + currentArray = currentArray[currentArray.length - 1]; - if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") && - !IsCmd(obj, "}") && !IsCmd(obj, "]")) { - dump("Adding: " + obj); - operandStack.peek().push(obj); - this.getObj(); - } else if (IsCmd(obj, "{") || IsCmd(obj, "[")) { - dump("Start" + (obj.cmd == "{" ? " Executable " : " ") + "Array"); - operandIsArray ? operandStack.peek().push([]) : operandStack.push([]); - operandIsArray++; - this.getObj(); - } else if (IsCmd(obj, "}") || IsCmd(obj, "]")) { - dump("End" + (obj.cmd == "}" ? " Executable " : " ") + "Array"); - operandIsArray--; - this.getObj(); - } else if (IsCmd(obj, "if")) { - log("if"); - var procedure = operandStack.pop(); - var bool = operandStack.pop(); - if (!IsBool(bool)) { - executionStack.push(bool); - log("....."); - this.getObj(); - } - log(bool); - if (bool) - executionStack.push(procedure); - - this.getObj(); - } else if (IsCmd(obj, "ifelse")) { - log("ifelse"); - var procedure1 = operandStack.pop(); - var procedure2 = operandStack.pop(); - var bool = !!operandStack.pop(); - operandStack.push(bool ? procedure1 : procedure2); - this.getObj(); + currentArray.push(obj); + return parseNext(); } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { dump("Value: " + obj); operandStack.push(obj); - this.getObj(); - } else if (IsCmd(obj, "dup")) { - dump("Duplicate"); - operandStack.push(operandStack.peek()); - this.getObj(); - } else if (IsCmd(obj, "put") || IsCmd(obj, "NP")) { - operandStack.toString(); - - var data = operandStack.pop(); - var indexOrKey = operandStack.pop(); - var object = operandStack.pop(); - log(object); - log("put " + data + " in " + obj + "[" + indexOrKey + "]"); - - if (object.set) - object.set(indexOrKey, data); - else - object[indexOrKey] = data; - this.getObj(); - } else if (IsCmd(obj, "currentdict")) { - dump("currentdict"); - operandStack.push(dictionaryStack.peek()); - this.getObj(); - } else if (IsCmd(obj, "systemdict")) { - dump("systemdict"); - operandStack.push(systemDict); - this.getObj(); - } else if (IsCmd(obj, "readonly") || IsCmd(obj, "executeonly") || - IsCmd(obj, "noaccess") || IsCmd(obj, "currentfile")) { - // Do nothing for the moment - this.getObj(); + return parseNext(); } else if (IsName(obj)) { - //dump("Name: " + obj.name); + dump("Name: " + obj.name); operandStack.push(obj.name); - this.getObj(); - } else if (IsCmd(obj, "array")) { - var size = operandStack.pop(); - var array = new Array(size); - operandStack.push(array); - this.getObj(); - } else if (IsCmd(obj, "dict")) { - dump("Dict: " + obj); - var size = operandStack.pop(); - var dict = new Dict(size); - operandStack.push(dict); - this.getObj(); - } else if (IsCmd(obj, "begin")) { - dump("begin a dictionary"); - dictionaryStack.push(operandStack.pop()); - this.getObj(); - } else if (IsCmd(obj, "end")) { - dump("Ending a dictionary"); - dictionaryStack.pop(); - this.getObj(); - } else if (IsCmd(obj, "def") || IsCmd(obj, "ND")) { - var value = operandStack.pop(); - var key = operandStack.pop(); - log("def: " + key + " = " + value); - dictionaryStack.peek().set(key, value); - this.getObj(); - } else if (IsCmd(obj, "eexec")) { - // All the first segment data has been read, decrypt the second segment - // and start interpreting it in order to decode it - var eexecString = decrypt(aBinaryStream, kEexecEncryptionKey, 4).join(""); - lexer = new Lexer(new StringStream(eexecString)); + return parseNext(); + } else if (IsCmd(obj)) { + var command = obj.cmd; + dump(command); - this.getObj(); - } else if (IsCmd(obj, "known")) { - dump("known"); - var name = operandStack.pop(); - var dict = operandStack.pop(); - operandStack.push(!!dict.get(name)); - this.getObj(); - } else if (IsCmd(obj, "RD")) { - dump("RD"); - var size = operandStack.pop(); - var key = operandStack.pop(); + switch (command) { + case "[": + case "{": + dump("Start" + (command == "{" ? " Executable " : " ") + "Array"); + operandIsArray++; + var currentArray = operandStack; + for (var i = 1; i < operandIsArray; i++) + if (currentArray.peek) + currentArray = currentArray.peek(); + else + currentArray = currentArray[currentArray.length - 1]; + currentArray.push([]); + break; - // Add '1' because of the space separator, this is dirty - var stream = lexer.stream.makeSubStream(lexer.stream.pos + 1, size); - lexer.stream.skip(size + 1); + case "]": + case "}": + var currentArray = operandStack.peek(); + for (var i = 1; i < operandIsArray; i++) + currentArray = currentArray[currentArray.length - 1]; + dump("End" + (command == "}" ? " Executable " : " ") + "Array: " + currentArray.join(" ")); + operandIsArray--; + break; - var charString = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); - var charStream = new StringStream(charString); + case "if": + var procedure = operandStack.pop(); + var bool = operandStack.pop(); + if (!IsBool(bool)) { + dump("if: " + bool); + // we need to execute things, let be dirty + executionStack.push(bool); + } else { + dump("if ( " + bool + " ) { " + procedure + " }"); + if (bool) + executionStack.push(procedure); + } + break; - // XXX do we want to store that on the top dictionary or somewhere else - dictionaryStack.peek().set(key, charStream); + case "ifelse": + var procedure1 = operandStack.pop(); + var procedure2 = operandStack.pop(); + var bool = !!operandStack.pop(); + dump("if ( " + bool + " ) { " + procedure2 + " } else { " + procedure1 + " }"); + executionStack.push(bool ? procedure2 : procedure1); + break; - var decodedCharString = decodeCharString(charStream); - dump(decodedCharString); + case "dup": + //log("duplicate: " + operandStack.peek()); + operandStack.push(operandStack.peek()); + break; - this.getObj(); - } else if (IsCmd(obj, "LenIV")) { - error("LenIV: argh! we need to modify the length of discard characters for charStrings"); - } else if (IsCmd(obj, "closefile")) { - // End of binary data; - } else if (IsCmd(obj, "index")) { - var operands = []; - var size = operandStack.pop(); - for (var i = 0; i < size; i++) - operands.push(operandStack.pop()); + case "mark": + operandStack.push("mark"); + break; - var newOperand = operandStack.peek(); + case "cleartomark": + var command = ""; + do { + command = operandStack.pop(); + } while (command != "mark"); + break; - for (var i = 0; i < operands.length; i++) - operandStack.push(operands.pop()); + case "put": + var data = operandStack.pop(); + var indexOrKey = operandStack.pop(); + var object = operandStack.pop(); + //dump("put " + data + " in " + object + "[" + indexOrKey + "]"); + object.set ? object.set(indexOrKey, data) + : object[indexOrKey] = data; - operandStack.push(newOperand); - this.getObj(); - } else if (IsCmd(obj, "StandardEncoding")) { - // For some reason the value is considered as a command, maybe it is - // because of the uppercae 'S' - operandStack.push(obj.cmd); - this.getObj(); - } else { - var command = null; - if (IsCmd(obj)) { - for (var i = 0; i < dictionaryStack.length; i++) { - command = dictionaryStack.get(i).get(obj.cmd); - if (command) - break; - } + break; + + case "pop": + operandStack.pop(); + break; + + case "exch": + var operand1 = operandStack.pop(); + var operand2 = operandStack.pop(); + operandStack.push(operand1); + operandStack.push(operand2); + break; + + case "get": + var indexOrKey = operandStack.pop(); + var object = operandStack.pop(); + log("=============="); + operandStack.toString(); + log(dictionaryStack.__innerStack__); + log(object + "::" + indexOrKey); + var data = object.get ? object.get(indexOrKey) : object[indexOrKey]; + dump("get " + obj + "[" + indexOrKey + "]: " + data); + operandStack.push(data); + break; + + case "currentdict": + var dict = dictionaryStack.peek(); + operandStack.push(dict); + break; + + case "systemdict": + operandStack.push(systemDict); + break; + + case "readonly": + case "executeonly": + case "noaccess": + // Do nothing for the moment + break; + + case "currentfile": + operandStack.push("currentfile"); + break; + + case "array": + var size = operandStack.pop(); + var array = new Array(size); + operandStack.push(array); + break; + + case "dict": + var size = operandStack.pop(); + var dict = new Dict(size); + operandStack.push(dict); + break; + + case "begin": + dictionaryStack.push(operandStack.pop()); + break; + + case "end": + dictionaryStack.pop(); + break; + + case "def": + var value = operandStack.pop(); + var key = operandStack.pop(); + dump("def: " + key + " = " + value); + dictionaryStack.peek().set(key, value); + break; + + case "definefont": + var font = operandStack.pop(); + var key = operandStack.pop(); + dump("definefont " + font + " with key: " + key); + Font.set(key, font); + break; + + case "known": + var name = operandStack.pop(); + var dict = operandStack.pop(); + var data = !!dict.get(name); + dump("known: " + data + " :: " + name + " in dict: " + dict); + operandStack.push(data); + break; + + case "exec": + executionStack.push(operandStack.pop()); + break; + + case "eexec": + // All the first segment data has been read, decrypt the second segment + // and start interpreting it in order to decode it + var eexecString = decrypt(aBinaryStream, kEexecEncryptionKey, 4).join(""); + lexer = new Lexer(new StringStream(eexecString)); + break; + + case "LenIV": + error("LenIV: argh! we need to modify the length of discard characters for charStrings"); + break; + + case "closefile": + var file = operandStack.pop(); + return; + break; + + case "index": + var operands = []; + var size = operandStack.pop(); + for (var i = 0; i < size; i++) + operands.push(operandStack.pop()); + + var newOperand = operandStack.peek(); + + for (var i = 0; i < operands.length; i++) + operandStack.push(operands.pop()); + + operandStack.push(newOperand); + break; + + case "string": + var size = operandStack.pop(); + var str = (new Array(size + 1)).join(" "); + operandStack.push(str); + break; + + case "readstring": + var str = operandStack.pop(); + var size = str.length; + + var file = operandStack.pop(); + + // Add '1' because of the space separator, this is dirty + var stream = lexer.stream.makeSubStream(lexer.stream.pos + 1, size); + lexer.stream.skip(size + 1); + + var charString = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); + var charStream = new StringStream(charString); + var decodedCharString = decodeCharString(charStream); + dump("decodedCharString: " + decodedCharString); + operandStack.push(decodedCharString); + // boolean indicating if the operation is a success or not + operandStack.push(true); + break; + + case "StandardEncoding": + // For some reason the value is considered as a command, maybe it is + // because of the uppercase 'S' + operandStack.push(obj.cmd); + break; + + default: + var command = null; + if (IsCmd(obj)) { + for (var i = 0; i < dictionaryStack.length; i++) { + if (command = dictionaryStack.get(i).get(obj.cmd)) { + dump("found in dictionnary for " + obj.cmd + " command: " + command); + executionStack.push(command.slice()); + break; + } + } + } + + if (!command) { + log("operandStack: " + operandStack); + log("dictionaryStack: " + dictionaryStack); + log(obj); + error("Unknow command while parsing font"); + } + break; } - if (command) { - // XXX add the command to the execution stack - this.getObj(); - } else { - log("operandStack: " + operandStack); - log("dictionaryStack: " + dictionaryStack); - dump(obj); - error("Unknow token while parsing font"); - } + return parseNext(); + } else if (obj){ + log (obj); + operandStack.push(obj); + return parseNext(); } - - return operandStack.peek(); } }; @@ -467,8 +569,7 @@ var Type1Font = function(aFontName, aFontFile) { this.parser = new Type1Parser(ASCIIStream, binaryStream); - var fontDictionary = this.parser.getObj(); - log(fontDictionary + "\t" + "fontInfo: " + fontDictionary.get("FontInfo")); + this.parser.getObj(); hack = true; } From c663d181f907ba20304bf59857bd5af032386926 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 3 Jun 2011 17:54:40 +0200 Subject: [PATCH 07/77] Remove some debug leftover --- PDFFont.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 00d9bd517..22fe69858 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,11 +1,14 @@ -var Font = new Dict(); +/* + * This dictionary hold the decoded fonts + */ +var Fonts = new Dict(); var Type1Parser = function(aAsciiStream, aBinaryStream) { var lexer = new Lexer(aAsciiStream); // Turn on this flag for additional debugging logs - var debug = true; + var debug = false; var dump = function(aData) { if (debug) @@ -350,7 +353,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { break; case "dup": - //log("duplicate: " + operandStack.peek()); + dump("duplicate: " + operandStack.peek()); operandStack.push(operandStack.peek()); break; @@ -389,10 +392,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { case "get": var indexOrKey = operandStack.pop(); var object = operandStack.pop(); - log("=============="); - operandStack.toString(); - log(dictionaryStack.__innerStack__); - log(object + "::" + indexOrKey); var data = object.get ? object.get(indexOrKey) : object[indexOrKey]; dump("get " + obj + "[" + indexOrKey + "]: " + data); operandStack.push(data); @@ -448,7 +447,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var font = operandStack.pop(); var key = operandStack.pop(); dump("definefont " + font + " with key: " + key); - Font.set(key, font); + Fonts.set(key, font); break; case "known": @@ -547,7 +546,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { return parseNext(); } else if (obj){ - log (obj); + dump("unknow: " + obj); operandStack.push(obj); return parseNext(); } From a08691313f3cfd8e524484a432ab6ef773b39541 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 3 Jun 2011 19:47:07 +0200 Subject: [PATCH 08/77] Clean up some code and add some changes to pdf.js --- PDFFont.js | 142 ++++++++++++++++++++++++++++------------------------- pdf.js | 6 +++ 2 files changed, 81 insertions(+), 67 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 22fe69858..6a7c49b7b 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -15,6 +15,24 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { log(aData); }; + /* + * Parse a whole Type1 font stream (from the first segment to the last) + * assuming the 'eexec' block is binary data and fill up the 'Fonts' + * dictionary with the font informations. + */ + var self = this; + this.parse = function() { + if (!debug) { + while (!processNextToken()) {}; + } else { + // debug mode is used to debug postcript processing + setTimeout(function() { + if (!processNextToken()) + self.parse(); + }, 0); + } + } + /* * 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 @@ -24,6 +42,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var kCharStringsEncryptionKey = 4330; function decrypt(aStream, aKey, aDiscardNumber) { + var start = Date.now(); var r = aKey, c1 = 52845, c2 = 22719; var decryptedString = []; @@ -34,6 +53,8 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { 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); } @@ -75,37 +96,39 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * 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", + "9": "closepath", + "10": "callsubr", + "11": "return", + "12": { + "0": "dotsection", + "1": "vstem3", + "3": "hstem3", + "6": "seac", + "7": "sbw", + "12": "div", + "16": "callothersubr", + "17": "pop", + "33": "setcurrentpoint" + }, + "13": "hsbw", + "14": "endchar", + "21": "rmoveto", + "22": "hmoveto", + "30": "vhcurveto", + "31": "hcurveto" + }; + function decodeCharString(aStream) { + var start = Date.now(); var charString = []; - var cmd = { - "1": "hstem", - "3": "vstem", - "4": "vmoveto", - "5": "rlineto", - "6": "hlineto", - "7": "vlineto", - "8": "rrcurveto", - "9": "closepath", - "10": "callsubr", - "11": "return", - "12": { - "0": "dotsection", - "1": "vstem3", - "3": "hstem3", - "6": "seac", - "7": "sbw", - "12": "div", - "16": "callothersubr", - "17": "pop", - "33": "setcurrentpoint" - }, - "13": "hsbw", - "14": "endchar", - "21": "rmoveto", - "22": "hmoveto", - "30": "vhcurveto", - "31": "hcurveto" - } var value = ""; var count = aStream.length; @@ -116,10 +139,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { continue; } else if (value < 32) { if (value == 12) { - value = cmd["12"][aStream.getByte()]; + value = charStringDictionary["12"][aStream.getByte()]; count++; } else { - value = cmd[value]; + value = charStringDictionary[value]; } } else if (value <= 246) { value = parseInt(value) - 139; @@ -136,6 +159,8 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { charString.push(value); } + var end = Date.now(); + dump("Time to decode charString of length " + count + " is " + (end - start)); return charString; } @@ -259,6 +284,9 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { } }; + /* + * Return the next token in the execution stack + */ function nextInStack() { var currentProcedure = executionStack.peek(); if (currentProcedure) { @@ -271,20 +299,15 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { return lexer.getObj(); }; - var self = this; - function parseNext() { - setTimeout(function() { - self.getObj(); - }, 0); - }; /* - * Parse a font file from the first segment to the last assuming the eexec - * block is binary data. + * Get the next token from the executionStack and process it. + * Actually the function does not process the third segment of a Type1 font + * and end on 'closefile'. * * The method thrown an error if it encounters an unknown token. */ - this.getObj = function() { + function processNextToken() { var obj = nextInStack(); if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") && !IsCmd(obj, "]") && !IsCmd(obj, "}")) { @@ -294,15 +317,12 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { currentArray = currentArray[currentArray.length - 1]; currentArray.push(obj); - return parseNext(); } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { dump("Value: " + obj); operandStack.push(obj); - return parseNext(); } else if (IsName(obj)) { dump("Name: " + obj.name); operandStack.push(obj.name); - return parseNext(); } else if (IsCmd(obj)) { var command = obj.cmd; dump(command); @@ -475,7 +495,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { case "closefile": var file = operandStack.pop(); - return; + return true; break; case "index": @@ -543,48 +563,36 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { } break; } - - return parseNext(); } else if (obj){ dump("unknow: " + obj); operandStack.push(obj); - return parseNext(); } + + return false; } }; -var hack = false; + +var hack = true; var Type1Font = function(aFontName, aFontFile) { // All Type1 font program should begin with the comment %! if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); - if (!hack) { - log(aFontName); + if (hack) { + var start = Date.now(); var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); this.parser = new Type1Parser(ASCIIStream, binaryStream); + this.parser.parse(); - this.parser.getObj(); - hack = true; + var end = Date.now(); + dump("Time to parse font is:" + (end - start)); + + hack = false; } - - - this.info = {}; - this.name = aFontName; - this.encoding = []; - this.paintType = 0; - this.fontType = 0; - this.fontMatrix = []; - this.fontBBox = []; - this.uniqueID = 0; - this.metrics = {}; - this.strokeWidth = 0.0; - this.private = {}; - this.charStrings = {} - this.FID = 0; }; diff --git a/pdf.js b/pdf.js index 8caac0362..001882ad3 100644 --- a/pdf.js +++ b/pdf.js @@ -1002,6 +1002,9 @@ var Name = (function() { } constructor.prototype = { + toString: function() { + return this.name; + } }; return constructor; @@ -1013,6 +1016,9 @@ var Cmd = (function() { } constructor.prototype = { + toString: function() { + return this.cmd; + } }; return constructor; From c166db13fd1061e710ca5eb366a151345769510d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sat, 4 Jun 2011 00:43:50 +0200 Subject: [PATCH 09/77] Add the 'for' keyword and support 2's complement signed integer --- PDFFont.js | 43 +++++++++++++++++++++++++++++-------------- pdf.js | 4 ++++ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 6a7c49b7b..51e8282d1 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -153,7 +153,11 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { value = -((value - 251) * 256) - parseInt(aStream.getByte()) - 108; count++; } else { - error("Two complement signed integers are ignored for the moment"); + var byte = aStream.getByte(); + var high = (byte >> 1); + value = (byte - high) * 16777216 + aStream.getByte() * 65536 + + aStream.getByte() * 256 * + aStream.getByte(); + count += 4; } charString.push(value); @@ -372,6 +376,17 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { executionStack.push(bool ? procedure2 : procedure1); break; + case "for": + var procedure = operandStack.pop(); + var limit = operandStack.pop(); + var increment = operandStack.pop(); + var initial = operandStack.pop(); + for (var i = 0; i < limit; i += increment) { + operandStack.push(i); + executionStack.push(procedure.slice()); + } + break; + case "dup": dump("duplicate: " + operandStack.peek()); operandStack.push(operandStack.peek()); @@ -459,6 +474,12 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { case "def": var value = operandStack.pop(); var key = operandStack.pop(); + + if (key == "FontName" && Fonts.get(value)) { + // The font has already be decoded, stop! + return true; + } + dump("def: " + key + " = " + value); dictionaryStack.peek().set(key, value); break; @@ -573,26 +594,20 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }; -var hack = true; - var Type1Font = function(aFontName, aFontFile) { // All Type1 font program should begin with the comment %! if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); - if (hack) { - var start = Date.now(); + var start = Date.now(); - var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); - var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); + var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); + var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); - this.parser = new Type1Parser(ASCIIStream, binaryStream); - this.parser.parse(); + this.parser = new Type1Parser(ASCIIStream, binaryStream); + this.parser.parse(); - var end = Date.now(); - dump("Time to parse font is:" + (end - start)); - - hack = false; - } + var end = Date.now(); + dump("Time to parse font is:" + (end - start)); }; diff --git a/pdf.js b/pdf.js index 001882ad3..cca5ae730 100644 --- a/pdf.js +++ b/pdf.js @@ -2291,6 +2291,10 @@ var CanvasGraphics = (function() { TODO("support Type3 font"); break; + case "TrueType": + TODO("implement TrueType support"); + break; + default: error("Unsupported font type: " + subtype); break; From 4d261759d924550bd16b134d54245227b354f37d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 7 Jun 2011 19:17:46 +0200 Subject: [PATCH 10/77] Support TrueType Font --- PDFFont.js | 28 +++++++++++++++++++++++++++- pdf.js | 9 ++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 51e8282d1..3f494070f 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -4,6 +4,32 @@ */ var Fonts = new Dict(); + +var Base64Encoder = { + encode: function(aData) { + var str = []; + var count = aData.length; + for (var i = 0; i < count; i++) + str.push(aData.getChar()); + + return window.btoa(str.join("")); + } +}; + + +var TrueTypeFont = function(aFontName, aFontFile) { + if (Fonts.get(aFontName)) + return; + + //log("Loading a TrueType font: " + aFontName); + var fontData = Base64Encoder.encode(aFontFile); + Fonts.set(aFontName, fontData); + + // Add the css rule + var url = "url(data:font/ttf;base64," + fontData + ");"; + document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); +}; + var Type1Parser = function(aAsciiStream, aBinaryStream) { var lexer = new Lexer(aAsciiStream); @@ -608,6 +634,6 @@ var Type1Font = function(aFontName, aFontFile) { this.parser.parse(); var end = Date.now(); - dump("Time to parse font is:" + (end - start)); + //log("Time to parse font is:" + (end - start)); }; diff --git a/pdf.js b/pdf.js index cca5ae730..15198c553 100644 --- a/pdf.js +++ b/pdf.js @@ -2292,7 +2292,14 @@ var CanvasGraphics = (function() { break; case "TrueType": - TODO("implement TrueType support"); + var fontDescriptor = font.get("FontDescriptor"); + if (fontDescriptor.num) { + var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); + var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile2")); + fontName = fontDescriptor.get("FontName").name; + fontName = fontName.replace("+", ""); // no + are allowed in the font name + font = new TrueTypeFont(fontName, fontFile); + } break; default: From c098f0b31fa85cb80636b36afa8bb8d482af1f6c Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 8 Jun 2011 17:26:29 +0200 Subject: [PATCH 11/77] Fix some bugs and add the beginning of a Type2 reader --- PDFFont.js | 279 ++++++++++++++++++++- cffStandardStrings.js | 552 ++++++++++++++++++++++++++++++++++++++++++ pdf.js | 5 +- test.html | 1 + 4 files changed, 828 insertions(+), 9 deletions(-) create mode 100644 cffStandardStrings.js diff --git a/PDFFont.js b/PDFFont.js index 3f494070f..b8ce52e07 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -17,6 +17,8 @@ var Base64Encoder = { }; + + var TrueTypeFont = function(aFontName, aFontFile) { if (Fonts.get(aFontName)) return; @@ -30,6 +32,7 @@ var TrueTypeFont = function(aFontName, aFontFile) { document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); }; + var Type1Parser = function(aAsciiStream, aBinaryStream) { var lexer = new Lexer(aAsciiStream); @@ -211,6 +214,8 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }, pop: function() { + if (!this.length) + throw new Error("stackunderflow"); return this.__innerStack__.pop(); }, @@ -220,10 +225,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { return this.__innerStack__[this.__innerStack__.length - 1]; }, - toString: function() { + dump: function() { log("=== Start Dumping operandStack ==="); var str = []; - for (var i = 0; i < this.__innerStack__.length; i++) + for (var i = 0; i < this.length; i++) log(this.__innerStack__[i]); log("=== End Dumping operandStack ==="); }, @@ -257,7 +262,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }, pop: function() { - if (this.__innerStack__.length == 2) + if (this.__innerStack__.length == 3) return null; return this.__innerStack__.pop(); @@ -275,7 +280,15 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { get length() { return this.__innerStack__.length; - } + }, + + dump: function() { + log("=== Start Dumping dictionaryStack ==="); + var str = []; + for (var i = 0; i < this.length; i++) + log(this.__innerStack__[i]); + log("=== End Dumping dictionaryStack ==="); + }, }; /* @@ -433,10 +446,9 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var data = operandStack.pop(); var indexOrKey = operandStack.pop(); var object = operandStack.pop(); - //dump("put " + data + " in " + object + "[" + indexOrKey + "]"); + dump("put " + data + " in " + object + "[" + indexOrKey + "]"); object.set ? object.set(indexOrKey, data) : object[indexOrKey] = data; - break; case "pop": @@ -454,7 +466,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var indexOrKey = operandStack.pop(); var object = operandStack.pop(); var data = object.get ? object.get(indexOrKey) : object[indexOrKey]; - dump("get " + obj + "[" + indexOrKey + "]: " + data); + dump("get " + object + "[" + indexOrKey + "]: " + data); operandStack.push(data); break; @@ -501,6 +513,8 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var value = operandStack.pop(); var key = operandStack.pop(); + // XXX we don't want to do that here but for some reasons the names + // are different between what is declared and the FontName directive if (key == "FontName" && Fonts.get(value)) { // The font has already be decoded, stop! return true; @@ -515,6 +529,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var key = operandStack.pop(); dump("definefont " + font + " with key: " + key); Fonts.set(key, font); + operandStack.push(font); break; case "known": @@ -532,7 +547,9 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { case "eexec": // All the first segment data has been read, decrypt the second segment // and start interpreting it in order to decode it + var file = operandStack.pop(); var eexecString = decrypt(aBinaryStream, kEexecEncryptionKey, 4).join(""); + dump(eexecString); lexer = new Lexer(new StringStream(eexecString)); break; @@ -553,7 +570,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var newOperand = operandStack.peek(); - for (var i = 0; i < operands.length; i++) + while (operands.length) operandStack.push(operands.pop()); operandStack.push(newOperand); @@ -620,11 +637,14 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }; +var type1hack = false; var Type1Font = function(aFontName, aFontFile) { // All Type1 font program should begin with the comment %! if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); + if (!type1hack) { + type1hack= true; var start = Date.now(); var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); @@ -635,5 +655,248 @@ var Type1Font = function(aFontName, aFontFile) { var end = Date.now(); //log("Time to parse font is:" + (end - start)); + + this.convert(); + } }; +var hack = false; +Type1Font.prototype = { + convert: function() { + var fontName = "TACTGM+NimbusRomNo9L-Medi"; + var fontData = null; + for (var font in Fonts.map) { + if (font == fontName) { + fontData = Fonts.get(font); + break; + } + } + + if (!fontData || hack) + return; + hack = true; + + var t1Only = [ + "callothersubr", + "closepath", + "dotsection", + "hsbw", + "hstem3", + "pop", + "sbw", + "seac", + "setcurrentpoint", + "vstem3" + ]; + + /* + * The sequence and form of a Type 2 charstring program may be + * represented as: + * w? {hs* vs* cm* hm* mt subpath}? {mt subpath}* endchar + * + */ + var t2CharStrings = new Dict(); + + var t1CharStrings = fontData.get("CharStrings"); + for (var key in t1CharStrings.map) { + var font = t1CharStrings.get(key); + var t2font = []; + + for (var i = 0; i < font.length; i++) { + var token = font[i]; + switch (token) { + case "hsbw": + var width = t2font.pop(); + var leftSidebearingPoint = t2font.pop(); + font.push(width); + break; + default: + if (t1Only.indexOf(token) != -1) { + log(token + " need convert!\n"); + throw new Error("Type1 Only token"); + } + t2font.push(token); + break; + } + } + log(key + "::" + t1CharStrings.get(key)); + log("type2::" + t2font); + } + } +}; + +function decodeType2DictData(aString, aDictionary) { + var data = []; + + var value = ""; + var count = aString.length; + for (var i = 0; i < count; i) { + value = aString[i++]; + + if (value < 0) { + continue; + } else if (value == 28) { + value = aString[i++] << 8 | aString[i++]; + } else if (value == 29) { + value = aString[i++] << 24 | + aString[i++] << 16 | + aString[i++] << 8 | + aString[i++]; + } else if (value < 32) { + if (value == 12) { + value = aDictionary["12"][aString[i++]]; + } else { + value = aDictionary[value]; + } + } else if (value <= 246) { + value = parseInt(value) - 139; + } else if (value <= 250) { + value = ((value - 247) * 256) + parseInt(aString[i++]) + 108; + } else if (value <= 254) { + value = -((value - 251) * 256) - parseInt(aString[i++]) - 108; + } else { + throw new Error("Value should not be 255"); + } + + data.push(value); + } + + return data; +} + +var Type2Parser = function(aFilePath) { + var font = new Dict(); + + // Turn on this flag for additional debugging logs + var debug = true; + + function dump(aStr) { + if (debug) + log(aStr); + }; + + function readIndex(aStream, aIsByte) { + var count = aStream.getByte() + aStream.getByte(); + var offsize = aStream.getByte(); + var offsets = []; + for (var i = 0; i < count + 1; i++) { + var offset = 0; + for (var j = 0; j < offsize; j++) { + // XXX need to do some better code here + var byte = aStream.getByte(); + offset += byte; + } + offsets.push(offset); + } + + dump("Found " + count + " objects at offsets :" + offsets + " (offsize: " + offsize + ")"); + var dataOffset = aStream.pos; + var objects = []; + for (var i = 0; i < count; i++) { + var offset = offsets[i]; + aStream.pos = dataOffset + 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()); + dump("object at offset " + offset + " is: " + data); + objects.push(data); + } + return objects; + }; + + function parseAsToken(aArray) { + var objects = []; + + var count = aArray.length; + for (var i = 0; i < count; i++) { + var decoded = decodeType2DictData(aArray[i], CFFDictOps); + + 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, { + size: stack.pop(), + offset: 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; + } + } + } + } + + return objects; + }; + + 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", readIndex(aStream)); + dump(font.get("Names")); + + // Read the Top Dict Index + dump("Reading Index: TopDict"); + var topDict = readIndex(aStream, true); + + // Read the String Index + dump("Reading Index: Strings"); + var strings = readIndex(aStream); + + // 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 + parseAsToken(topDict); + + for (var p in font.map) { + log(p + "::" + font.get(p)); + } + } +}; + +// +var xhr = new XMLHttpRequest(); +xhr.open("GET", "titi.cff", false); +xhr.mozResponseType = xhr.responseType = "arraybuffer"; +xhr.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200; +xhr.send(null); +var cffData = xhr.mozResponseArrayBuffer || xhr.mozResponse || + xhr.responseArrayBuffer || xhr.response; +var cff = new Type2Parser("titi.cff"); +cff.parse(new Stream(cffData)); + diff --git a/cffStandardStrings.js b/cffStandardStrings.js new file mode 100644 index 000000000..1604b5fdd --- /dev/null +++ b/cffStandardStrings.js @@ -0,0 +1,552 @@ +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", + "95 asciitilde", + "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 CFFDictOps = { + "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" + } +}; diff --git a/pdf.js b/pdf.js index 15198c553..ea6a62f57 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) @@ -78,7 +79,7 @@ var Stream = (function() { return ch; }, skip: function(n) { - if (!n) + if (!n && !IsNum(n)) n = 1; this.pos += n; }, @@ -2279,6 +2280,7 @@ var CanvasGraphics = (function() { var subtype = font.get("Subtype").name; switch (subtype) { case "Type1": + break; var fontDescriptor = font.get("FontDescriptor"); if (fontDescriptor.num) { var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); @@ -2292,6 +2294,7 @@ var CanvasGraphics = (function() { break; case "TrueType": + break; var fontDescriptor = font.get("FontDescriptor"); if (fontDescriptor.num) { var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); diff --git a/test.html b/test.html index ac568473a..5bd0ea119 100644 --- a/test.html +++ b/test.html @@ -5,6 +5,7 @@ + From 87b4cb85beddc2329148067bd633218993ded138 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 8 Jun 2011 20:37:25 +0200 Subject: [PATCH 12/77] Starts to decode type2 charStrings --- PDFFont.js | 232 +++++++++++++++++++++--------------------- cffStandardStrings.js | 149 ++++++++++++++++++++++++++- 2 files changed, 265 insertions(+), 116 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index b8ce52e07..755bea9b5 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -660,80 +660,19 @@ var Type1Font = function(aFontName, aFontFile) { } }; -var hack = false; -Type1Font.prototype = { - convert: function() { - var fontName = "TACTGM+NimbusRomNo9L-Medi"; - var fontData = null; - for (var font in Fonts.map) { - if (font == fontName) { - fontData = Fonts.get(font); - break; - } - } - if (!fontData || hack) - return; - hack = true; - var t1Only = [ - "callothersubr", - "closepath", - "dotsection", - "hsbw", - "hstem3", - "pop", - "sbw", - "seac", - "setcurrentpoint", - "vstem3" - ]; +/**************************************************************************/ - /* - * The sequence and form of a Type 2 charstring program may be - * represented as: - * w? {hs* vs* cm* hm* mt subpath}? {mt subpath}* endchar - * - */ - var t2CharStrings = new Dict(); - - var t1CharStrings = fontData.get("CharStrings"); - for (var key in t1CharStrings.map) { - var font = t1CharStrings.get(key); - var t2font = []; - - for (var i = 0; i < font.length; i++) { - var token = font[i]; - switch (token) { - case "hsbw": - var width = t2font.pop(); - var leftSidebearingPoint = t2font.pop(); - font.push(width); - break; - default: - if (t1Only.indexOf(token) != -1) { - log(token + " need convert!\n"); - throw new Error("Type1 Only token"); - } - t2font.push(token); - break; - } - } - log(key + "::" + t1CharStrings.get(key)); - log("type2::" + t2font); - } - } -}; - -function decodeType2DictData(aString, aDictionary) { +function decodeType2DictData(aString, aDictionary, aHack) { var data = []; var value = ""; var count = aString.length; for (var i = 0; i < count; i) { value = aString[i++]; - - if (value < 0) { + if (value <= 0) { + data.push(value); continue; } else if (value == 28) { value = aString[i++] << 8 | aString[i++]; @@ -743,11 +682,15 @@ function decodeType2DictData(aString, aDictionary) { aString[i++] << 8 | aString[i++]; } else if (value < 32) { + var oldValue = value; if (value == 12) { value = aDictionary["12"][aString[i++]]; } else { value = aDictionary[value]; } + if (!value) + throw new Error("This command number does not match anything : " + oldValue); + value = aHack ? value.name : value; } else if (value <= 246) { value = parseInt(value) - 139; } else if (value <= 250) { @@ -776,15 +719,30 @@ var Type2Parser = function(aFilePath) { }; function readIndex(aStream, aIsByte) { - var count = aStream.getByte() + aStream.getByte(); + var count = aStream.getByte() << 8 | aStream.getByte(); var offsize = aStream.getByte(); var offsets = []; for (var i = 0; i < count + 1; i++) { - var offset = 0; - for (var j = 0; j < offsize; j++) { - // XXX need to do some better code here - var byte = aStream.getByte(); - offset += byte; + switch (offsize) { + case 0: + offset = 0; + break; + case 1: + offset = aStream.getByte(); + break; + case 2: + offset = aStream.getByte() << 8 | aStream.getByte(); + break; + case 3: + offset = aStream.getByte() << 16 | aStream.getByte() << 8 | + aStream.getByte(); + break; + case 4: + offset = aStream.getByte() << 24 | aStream.getByte() << 16 | + aStream.getByte() << 8 | aStream.getByte(); + break; + default: + throw new Error("Unsupported offsize: " + offsize); } offsets.push(offset); } @@ -800,58 +758,73 @@ var Type2Parser = function(aFilePath) { var length = offsets[i + 1] - 1; for (var j = offset - 1; j < length; j++) data.push(aIsByte ? aStream.getByte() : aStream.getChar()); - dump("object at offset " + offset + " is: " + data); + //dump("object at offset " + offset + " is: " + data); objects.push(data); } return objects; }; - function parseAsToken(aArray) { - var objects = []; + function parseAsToken(aString, aDict) { + var decoded = decodeType2DictData(aString, aDict); - var count = aArray.length; + var stack = []; + var count = decoded.length; for (var i = 0; i < count; i++) { - var decoded = decodeType2DictData(aArray[i], CFFDictOps); - - 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, { - size: stack.pop(), - offset: stack.pop() - }); - break; - case "boolean": + 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, { + size: stack.pop(), + offset: 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; - 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; - } + } + break; } } } + }; - return objects; + + function readCharset(aStream, aCharStrings) { + var charset = {}; + + var format = aStream.getByte(); + if (format == 0) { + var count = aCharStrings.length - 1; + charset[".notdef"] = decodeType2DictData(aCharStrings[0], CFFDictCommands, true); + for (var i = 1; i < count + 1; i++) { + var sid = aStream.getByte() << 8 | aStream.getByte(); + var charString = decodeType2DictData(aCharStrings[i], CFFDictCommands, true); + charset[CFFStrings[sid]] = charString; + log(CFFStrings[sid] + "::" + charString); + } + } else if (format == 1) { + throw new Error("Format 1 charset are not supported"); + } else { + throw new Error("Invalid charset format"); + } + return charset; }; this.parse = function(aStream) { @@ -881,15 +854,44 @@ var Type2Parser = function(aFilePath) { CFFStrings.push(strings[i].join("")); // Parse the TopDict operator - parseAsToken(topDict); + var objects = []; + var count = topDict.length; + for (var i = 0; i < count; i++) + parseAsToken(topDict[i], CFFDictOps); - for (var p in font.map) { - log(p + "::" + font.get(p)); + for (var p in font.map) + dump(p + "::" + font.get(p)); + + // Read the Subr Index + dump("Reading Subr Index"); + var subrs = readIndex(aStream); + + // Read CharStrings Index + dump("Read CharStrings Index"); + var charStringsOffset = font.get("CharStrings"); + aStream.pos = charStringsOffset; + var charStrings = readIndex(aStream, true); + + + var charsetEntry = font.get("charset"); + if (charsetEntry == 0) { + throw new Error("Need to support CFFISOAdobeCharset"); + } else if (charsetEntry == 1) { + throw new Error("Need to support CFFExpert"); + } else if (charsetEntry == 2) { + throw new Error("Need to support CFFExpertSubsetCharset"); + } else { + aStream.pos = charsetEntry; + var charset = readCharset(aStream, charStrings); } + + // Read Encoding data + log("Reading encoding data"); } }; -// + +// XXX var xhr = new XMLHttpRequest(); xhr.open("GET", "titi.cff", false); xhr.mozResponseType = xhr.responseType = "arraybuffer"; diff --git a/cffStandardStrings.js b/cffStandardStrings.js index 1604b5fdd..ab71947ec 100644 --- a/cffStandardStrings.js +++ b/cffStandardStrings.js @@ -65,7 +65,7 @@ var CFFStrings = [ "asciicircum", "underscore", "quoteleft", - "95 asciitilde", + "a", "b", "c", "d", @@ -550,3 +550,150 @@ var CFFDictOps = { name: "nominalWidthX" } }; + +var CFFDictCommands = { + "1": { + name: "hstem" + }, + "3": { + name: "vstem" + }, + "4": { + name: "vmoveto" + }, + "5": { + name: "rlineto" + }, + "6": { + name: "hlineto" + }, + "7": { + name: "vlineto" + }, + "8": { + name: "rrcurveto" + }, + "10": { + name: "callsubr" + }, + "11": { + name: "return" + }, + "12": { + "3": { + name: "and" + }, + "4": { + name: "or" + }, + "5": { + name: "not" + }, + "9": { + name: "abs" + }, + "10": { + name: "add" + }, + "11": { + name: "div" + }, + "12": { + name: "sub" + }, + "14": { + name: "neg" + }, + "15": { + name: "eq" + }, + "18": { + name: "drop" + }, + "20": { + name: "put" + }, + "21": { + name: "get" + }, + "22": { + name: "ifelse" + }, + "23": { + name: "random" + }, + "24": { + name: "mul" + }, + "26": { + name: "sqrt" + }, + "27": { + name: "dup" + }, + "28": { + name: "exch" + }, + "29": { + name: "index" + }, + "30": { + name: "roll" + }, + "34": { + name: "hflex" + }, + "35": { + name: "flex" + }, + "36": { + name: "hflex1" + }, + "37": { + name: "flex1" + } + }, + "14": { + name: "endchar" + }, + "18": { + name: "hstemhm" + }, + "19": { + name: "hintmask" + }, + "20": { + name: "cntrmask" + }, + "21": { + name: "rmoveto" + }, + "22": { + name: "hmoveto" + }, + "23": { + name: "vstemhm" + }, + "24": { + name: "rcurveline" + }, + "25": { + name: "rlivecurve" + }, + "26": { + name: "vvcurveto" + }, + "27": { + name: "hhcurveto" + }, + "29": { + name: "callgsubr" + }, + "30": { + name: "vhcurveto" + }, + "31": { + name: "hvcurveto" + } +}; + From 714571dc807c91ce9555e64ac5f047a59b6260d4 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 9 Jun 2011 00:26:41 +0200 Subject: [PATCH 13/77] Support reading all parts of a Type2 file --- PDFFont.js | 89 +++++++++++++++++++++++++++++++++++-------- cffStandardStrings.js | 76 ++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 15 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 755bea9b5..a6363f940 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -664,7 +664,7 @@ var Type1Font = function(aFontName, aFontFile) { /**************************************************************************/ -function decodeType2DictData(aString, aDictionary, aHack) { +function decodeType2DictData(aString, aDictionary, aHack, aUseRealNumber) { var data = []; var value = ""; @@ -672,8 +672,6 @@ function decodeType2DictData(aString, aDictionary, aHack) { for (var i = 0; i < count; i) { value = aString[i++]; if (value <= 0) { - data.push(value); - continue; } else if (value == 28) { value = aString[i++] << 8 | aString[i++]; } else if (value == 29) { @@ -681,22 +679,72 @@ function decodeType2DictData(aString, aDictionary, aHack) { aString[i++] << 16 | aString[i++] << 8 | aString[i++]; + } else if (aUseRealNumber && value == 30) { + value = ""; + var done = false; + while (!done) { + var byte = aString[i++]; + var nibbles = [parseInt(byte / 16), parseInt(byte % 16)]; + for (var j = 0; j < nibbles.length; j++) { + var nibble = nibbles[j]; + dump(nibble + "\n"); + switch (nibble) { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + case 0x8: + case 0x9: + value += nibble; + break; + case 0xA: + value += "."; + break; + case 0xB: + value += "E"; + break; + case 0xC: + value += "E-"; + break; + case 0xD: + break; + case 0xE: + value += "-"; + break; + case 0xF: + done = true; + break; + default: + error(nibble + " is unssuported"); + break; + } + } + }; + value = parseFloat(value); } else if (value < 32) { - var oldValue = value; if (value == 12) { value = aDictionary["12"][aString[i++]]; - } else { + } else if (aDictionary[value]) { value = aDictionary[value]; + } else { + error(value + " is an invalid command number"); } - if (!value) - throw new Error("This command number does not match anything : " + oldValue); value = aHack ? value.name : value; } else if (value <= 246) { value = parseInt(value) - 139; } else if (value <= 250) { - value = ((value - 247) * 256) + parseInt(aString[i++]) + 108; + value = ((value - 247) * 256) + aString[i++] + 108; } else if (value <= 254) { - value = -((value - 251) * 256) - parseInt(aString[i++]) - 108; + value = -((value - 251) * 256) - aString[i++] - 108; + } else if (value == 255) { + var byte = aString[i++]; + var high = (byte >> 1); + value = (byte - high) << 24 | aString[i++] << 16 | + aString[i++] << 8 | aString[i]; } else { throw new Error("Value should not be 255"); } @@ -780,8 +828,8 @@ var Type2Parser = function(aFilePath) { break; case "number number": font.set(token.name, { - size: stack.pop(), - offset: stack.pop() + offset: stack.pop(), + size: stack.pop() }); break; case "boolean": @@ -859,16 +907,19 @@ var Type2Parser = function(aFilePath) { for (var i = 0; i < count; i++) parseAsToken(topDict[i], CFFDictOps); + var topDictOffset = aStream.pos; + for (var p in font.map) dump(p + "::" + font.get(p)); - // Read the Subr Index + // Read the Global Subr Index that comes just after the Strings Index + // (cf. "The Compact Font Format Specification" Chapter 16) dump("Reading Subr Index"); var subrs = readIndex(aStream); // Read CharStrings Index - dump("Read CharStrings Index"); var charStringsOffset = font.get("CharStrings"); + dump("Read CharStrings Index (offset: " + charStringsOffset + ")"); aStream.pos = charStringsOffset; var charStrings = readIndex(aStream, true); @@ -885,8 +936,16 @@ var Type2Parser = function(aFilePath) { var charset = readCharset(aStream, charStrings); } - // Read Encoding data - log("Reading encoding data"); + // 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()); + log(privateDict); + log(decodeType2DictData(privateDict, CFFDictPrivate, true, true)); } }; diff --git a/cffStandardStrings.js b/cffStandardStrings.js index ab71947ec..25301ee31 100644 --- a/cffStandardStrings.js +++ b/cffStandardStrings.js @@ -697,3 +697,79 @@ var CFFDictCommands = { } }; +var CFFDictPrivate = { + "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 + } +}; From fcc4ce9bec1a4f1b01138e9fc66e8b5ec3ad1b68 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 9 Jun 2011 02:37:06 +0200 Subject: [PATCH 14/77] Clean up some Type2 reader code for readibility --- PDFFont.js | 361 +++++++++++++++++++++++++----------------- cffStandardStrings.js | 209 +++++++----------------- 2 files changed, 274 insertions(+), 296 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index a6363f940..084174dad 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -33,6 +33,8 @@ var TrueTypeFont = function(aFontName, aFontFile) { }; + + var Type1Parser = function(aAsciiStream, aBinaryStream) { var lexer = new Lexer(aAsciiStream); @@ -155,6 +157,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { "31": "hcurveto" }; + // XXX Is count++ the right thing to do? Is it not i++? function decodeCharString(aStream) { var start = Date.now(); var charString = []; @@ -184,8 +187,8 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { } else { var byte = aStream.getByte(); var high = (byte >> 1); - value = (byte - high) * 16777216 + aStream.getByte() * 65536 + - aStream.getByte() * 256 * + aStream.getByte(); + value = (byte - high) << 24 | aStream.getByte() << 16 | + aStream.getByte() << 8 | aStream.getByte(); count += 4; } @@ -662,98 +665,230 @@ var Type1Font = function(aFontName, aFontFile) { -/**************************************************************************/ -function decodeType2DictData(aString, aDictionary, aHack, aUseRealNumber) { - var data = []; - var value = ""; + + + + + + + + +/** + * 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. + */ + + +/** + * 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) { - value = aString[i++]; - if (value <= 0) { + var value = aString[i++]; + var token = null; + + if (value == 12) { + token = aMap[value][aString[i++]]; } else if (value == 28) { - value = aString[i++] << 8 | aString[i++]; + token = aString[i++] << 8 | aString[i++]; } else if (value == 29) { - value = aString[i++] << 24 | + token = aString[i++] << 24 | aString[i++] << 16 | aString[i++] << 8 | aString[i++]; - } else if (aUseRealNumber && value == 30) { - value = ""; - var done = false; - while (!done) { + } 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]; - dump(nibble + "\n"); switch (nibble) { - case 0x0: - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - case 0x8: - case 0x9: - value += nibble; - break; case 0xA: - value += "."; + token += "."; break; case 0xB: - value += "E"; + token += "E"; break; case 0xC: - value += "E-"; + token += "E-"; break; case 0xD: break; case 0xE: - value += "-"; + token += "-"; break; case 0xF: - done = true; + parsed = true; break; default: - error(nibble + " is unssuported"); + token += nibble; break; } } }; - value = parseFloat(value); - } else if (value < 32) { - if (value == 12) { - value = aDictionary["12"][aString[i++]]; - } else if (aDictionary[value]) { - value = aDictionary[value]; - } else { - error(value + " is an invalid command number"); - } - value = aHack ? value.name : value; + token = parseFloat(token); + } else if (value <= 31) { + token = aMap[value]; } else if (value <= 246) { - value = parseInt(value) - 139; + token = parseInt(value) - 139; } else if (value <= 250) { - value = ((value - 247) * 256) + aString[i++] + 108; + token = ((value - 247) * 256) + aString[i++] + 108; } else if (value <= 254) { - value = -((value - 251) * 256) - aString[i++] - 108; + token = -((value - 251) * 256) - aString[i++] - 108; } else if (value == 255) { - var byte = aString[i++]; - var high = (byte >> 1); - value = (byte - high) << 24 | aString[i++] << 16 | - aString[i++] << 8 | aString[i]; - } else { - throw new Error("Value should not be 255"); + error("255 is not a valid DICT command"); } - data.push(value); + fontDictDataTokens.push(token); } - return data; -} + 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(); @@ -766,54 +901,9 @@ var Type2Parser = function(aFilePath) { log(aStr); }; - function readIndex(aStream, aIsByte) { - var count = aStream.getByte() << 8 | aStream.getByte(); - var offsize = aStream.getByte(); - var offsets = []; - for (var i = 0; i < count + 1; i++) { - switch (offsize) { - case 0: - offset = 0; - break; - case 1: - offset = aStream.getByte(); - break; - case 2: - offset = aStream.getByte() << 8 | aStream.getByte(); - break; - case 3: - offset = aStream.getByte() << 16 | aStream.getByte() << 8 | - aStream.getByte(); - break; - case 4: - offset = aStream.getByte() << 24 | aStream.getByte() << 16 | - aStream.getByte() << 8 | aStream.getByte(); - break; - default: - throw new Error("Unsupported offsize: " + offsize); - } - offsets.push(offset); - } - - dump("Found " + count + " objects at offsets :" + offsets + " (offsize: " + offsize + ")"); - var dataOffset = aStream.pos; - var objects = []; - for (var i = 0; i < count; i++) { - var offset = offsets[i]; - aStream.pos = dataOffset + 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()); - //dump("object at offset " + offset + " is: " + data); - objects.push(data); - } - return objects; - }; - - function parseAsToken(aString, aDict) { - var decoded = decodeType2DictData(aString, aDict); + function parseAsToken(aString, aMap) { + var decoded = readFontDictData(aString, aMap); + log(decoded); var stack = []; var count = decoded.length; @@ -853,28 +943,6 @@ var Type2Parser = function(aFilePath) { } }; - - function readCharset(aStream, aCharStrings) { - var charset = {}; - - var format = aStream.getByte(); - if (format == 0) { - var count = aCharStrings.length - 1; - charset[".notdef"] = decodeType2DictData(aCharStrings[0], CFFDictCommands, true); - for (var i = 1; i < count + 1; i++) { - var sid = aStream.getByte() << 8 | aStream.getByte(); - var charString = decodeType2DictData(aCharStrings[i], CFFDictCommands, true); - charset[CFFStrings[sid]] = charString; - log(CFFStrings[sid] + "::" + charString); - } - } else if (format == 1) { - throw new Error("Format 1 charset are not supported"); - } else { - throw new Error("Invalid charset format"); - } - return charset; - }; - this.parse = function(aStream) { font.set("major", aStream.getByte()); font.set("minor", aStream.getByte()); @@ -886,16 +954,15 @@ var Type2Parser = function(aFilePath) { // Read the NAME Index dump("Reading Index: Names"); - font.set("Names", readIndex(aStream)); - dump(font.get("Names")); + font.set("Names", readFontIndexData(aStream)); // Read the Top Dict Index dump("Reading Index: TopDict"); - var topDict = readIndex(aStream, true); + var topDict = readFontIndexData(aStream, true); // Read the String Index dump("Reading Index: Strings"); - var strings = readIndex(aStream); + var strings = readFontIndexData(aStream); // Fill up the Strings dictionary with the new unique strings for (var i = 0; i < strings.length; i++) @@ -905,23 +972,31 @@ var Type2Parser = function(aFilePath) { var objects = []; var count = topDict.length; for (var i = 0; i < count; i++) - parseAsToken(topDict[i], CFFDictOps); - - var topDictOffset = aStream.pos; - - for (var p in font.map) - dump(p + "::" + font.get(p)); + 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 Subr Index"); - var subrs = readIndex(aStream); + dump("Reading Global Subr Index"); + var subrs = readFontIndexData(aStream); + + // 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()); + 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 = readIndex(aStream, true); + var charStrings = readFontIndexData(aStream, true); var charsetEntry = font.get("charset"); @@ -936,16 +1011,6 @@ var Type2Parser = function(aFilePath) { var charset = readCharset(aStream, charStrings); } - // 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()); - log(privateDict); - log(decodeType2DictData(privateDict, CFFDictPrivate, true, true)); } }; diff --git a/cffStandardStrings.js b/cffStandardStrings.js index 25301ee31..585c1157e 100644 --- a/cffStandardStrings.js +++ b/cffStandardStrings.js @@ -392,7 +392,66 @@ var CFFStrings = [ "Semibold" ]; -var CFFDictOps = { +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" @@ -551,153 +610,7 @@ var CFFDictOps = { } }; -var CFFDictCommands = { - "1": { - name: "hstem" - }, - "3": { - name: "vstem" - }, - "4": { - name: "vmoveto" - }, - "5": { - name: "rlineto" - }, - "6": { - name: "hlineto" - }, - "7": { - name: "vlineto" - }, - "8": { - name: "rrcurveto" - }, - "10": { - name: "callsubr" - }, - "11": { - name: "return" - }, - "12": { - "3": { - name: "and" - }, - "4": { - name: "or" - }, - "5": { - name: "not" - }, - "9": { - name: "abs" - }, - "10": { - name: "add" - }, - "11": { - name: "div" - }, - "12": { - name: "sub" - }, - "14": { - name: "neg" - }, - "15": { - name: "eq" - }, - "18": { - name: "drop" - }, - "20": { - name: "put" - }, - "21": { - name: "get" - }, - "22": { - name: "ifelse" - }, - "23": { - name: "random" - }, - "24": { - name: "mul" - }, - "26": { - name: "sqrt" - }, - "27": { - name: "dup" - }, - "28": { - name: "exch" - }, - "29": { - name: "index" - }, - "30": { - name: "roll" - }, - "34": { - name: "hflex" - }, - "35": { - name: "flex" - }, - "36": { - name: "hflex1" - }, - "37": { - name: "flex1" - } - }, - "14": { - name: "endchar" - }, - "18": { - name: "hstemhm" - }, - "19": { - name: "hintmask" - }, - "20": { - name: "cntrmask" - }, - "21": { - name: "rmoveto" - }, - "22": { - name: "hmoveto" - }, - "23": { - name: "vstemhm" - }, - "24": { - name: "rcurveline" - }, - "25": { - name: "rlivecurve" - }, - "26": { - name: "vvcurveto" - }, - "27": { - name: "hhcurveto" - }, - "29": { - name: "callgsubr" - }, - "30": { - name: "vhcurveto" - }, - "31": { - name: "hvcurveto" - } -}; - -var CFFDictPrivate = { +var CFFDictPrivateDataMap = { "6": { name: "BluesValues", operand: "delta" From 74abf984d5823f56179ca8f266d3eb320003aeaf Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 01:20:00 +0200 Subject: [PATCH 15/77] Add the beginning of a Type1 to Type2 charstring converter --- PDFFont.js | 358 ++++++++++++++++++++++++++++++++++++++++++++++++----- pdf.js | 2 +- test.html | 1 + 3 files changed, 328 insertions(+), 33 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 084174dad..5685e6874 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,9 +1,15 @@ - -/* - * This dictionary hold the decoded fonts +/** + * This dictionary holds decoded fonts data. */ var Fonts = new Dict(); +/** + * This simple object keep a trace of the fonts that have already been decoded + * by storing a map between the name given by the PDF and the name gather from + * the font (aka the PostScript code of the font itself for Type1 font). + */ +var _Fonts = {}; + var Base64Encoder = { encode: function(aData) { @@ -16,12 +22,10 @@ var Base64Encoder = { } }; - - - var TrueTypeFont = function(aFontName, aFontFile) { - if (Fonts.get(aFontName)) + if (_Fonts[aFontName]) return; + _Fonts[aFontName] = true; //log("Loading a TrueType font: " + aFontName); var fontData = Base64Encoder.encode(aFontFile); @@ -36,7 +40,16 @@ var TrueTypeFont = function(aFontName, aFontFile) { var Type1Parser = function(aAsciiStream, aBinaryStream) { - var lexer = new Lexer(aAsciiStream); + if (IsStream(aAsciiStream)) { + var lexer = new Lexer(aAsciiStream); + } else { + var lexer = { + __data__: aAsciiStream.slice(), + getObj: function() { + return this.__data__.shift(); + } + } + } // Turn on this flag for additional debugging logs var debug = false; @@ -46,6 +59,11 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { log(aData); }; + // Hold the fontName as declared inside the /FontName postscript directive + // XXX This is a hack but at the moment I need it to map the name declared + // in the PDF and the name in the PS code. + var fontName = ""; + /* * Parse a whole Type1 font stream (from the first segment to the last) * assuming the 'eexec' block is binary data and fill up the 'Fonts' @@ -55,6 +73,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { this.parse = function() { if (!debug) { while (!processNextToken()) {}; + return fontName; } else { // debug mode is used to debug postcript processing setTimeout(function() { @@ -62,7 +81,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { self.parse(); }, 0); } - } + }; /* * Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence @@ -87,7 +106,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { 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 @@ -98,7 +117,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * 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. @@ -110,7 +129,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * 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 @@ -157,7 +176,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { "31": "hcurveto" }; - // XXX Is count++ the right thing to do? Is it not i++? function decodeCharString(aStream) { var start = Date.now(); var charString = []; @@ -167,12 +185,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { for (var i = 0; i < count; i++) { value = aStream.getByte(); - if (value < 0) { - continue; - } else if (value < 32) { + if (value < 32) { if (value == 12) { value = charStringDictionary["12"][aStream.getByte()]; - count++; + i++; } else { value = charStringDictionary[value]; } @@ -180,16 +196,16 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { value = parseInt(value) - 139; } else if (value <= 250) { value = ((value - 247) * 256) + parseInt(aStream.getByte()) + 108; - count++; + i++; } else if (value <= 254) { value = -((value - 251) * 256) - parseInt(aStream.getByte()) - 108; - count++; + i++; } else { var byte = aStream.getByte(); var high = (byte >> 1); value = (byte - high) << 24 | aStream.getByte() << 16 | aStream.getByte() << 8 | aStream.getByte(); - count += 4; + i += 4; } charString.push(value); @@ -228,6 +244,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { return this.__innerStack__[this.__innerStack__.length - 1]; }, + get: function(aIndex) { + return this.__innerStack__[aIndex]; + }, + dump: function() { log("=== Start Dumping operandStack ==="); var str = []; @@ -345,7 +365,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { return lexer.getObj(); }; - /* * Get the next token from the executionStack and process it. * Actually the function does not process the third segment of a Type1 font @@ -531,7 +550,11 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var font = operandStack.pop(); var key = operandStack.pop(); dump("definefont " + font + " with key: " + key); + + // The key will be the identifier to recognize this font + fontName = key; Fonts.set(key, font); + operandStack.push(font); break; @@ -600,6 +623,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var decodedCharString = decodeCharString(charStream); dump("decodedCharString: " + decodedCharString); operandStack.push(decodedCharString); + // boolean indicating if the operation is a success or not operandStack.push(true); break; @@ -630,36 +654,305 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { } break; } - } else if (obj){ + } else if (obj) { dump("unknow: " + obj); operandStack.push(obj); + } else { // The End! + operandStack.dump(); + return true; } return false; } + + function aggregateCommand(aCommand) { + var command = aCommand; + switch (command) { + case "hstem": + case "vstem": + break; + + case "rrcurveto": + var stack = [operandStack.pop(), operandStack.pop(), + operandStack.pop(), operandStack.pop(), + operandStack.pop(), operandStack.pop()]; + var next = true; + while (next) { + var op = operandStack.peek(); + if (op == "rrcurveto") { + operandStack.pop(); + stack.push(operandStack.pop()); + stack.push(operandStack.pop()); + stack.push(operandStack.pop()); + stack.push(operandStack.pop()); + stack.push(operandStack.pop()); + stack.push(operandStack.pop()); + } else { + next = false; + } + } + break; + + case "hlineto": + case "vlineto": + var last = command; + var stack = [operandStack.pop()]; + var next = true; + while (next) { + var op = operandStack.peek(); + if (op == "vlineto" && last == "hlineto") { + operandStack.pop(); + stack.push(operandStack.pop()); + } else if (op == "hlineto" && last == "vlineto") { + operandStack.pop(); + stack.push(operandStack.pop()); + } else if (op == "rlineto" && command == "hlineto") { + operandStack.pop(); + var x = stack.pop(); + operandStack.push(0); + operandStack.push(x); + command = "rlineto"; + } else if (op == "rlineto" && command == "vlineto") { + operandStack.pop(); + operandStack.push(0); + command = "rlineto"; + } else { + next = false; + } + last = op; + } + break; + + case "rlineto": + var stack = [operandStack.pop(), operandStack.pop()]; + var next = true; + while (next) { + var op = operandStack.peek(); + if (op == "rlineto") { + operandStack.pop(); + stack.push(operandStack.pop()); + stack.push(operandStack.pop()); + } else if (op == "hlineto") { + operandStack.pop(); + stack.push(0); + stack.push(operandStack.pop()); + } else if (op == "vlineto") { + operandStack.pop(); + stack.push(operandStack.pop()); + stack.push(0); + } else { + next= false; + } + } + break; + } + + while (stack.length) + operandStack.push(stack.pop()); + operandStack.push(command); + }; + + + /* + * Flatten the commands by interpreting the postscript code and replacing + * every 'callsubr', 'callothersubr' by the real commands. + * At the moment OtherSubrs are not fully supported and only otherSubrs 0-4 + * as descrived in 'Using Subroutines' of 'Adobe Type 1 Font Format', + * chapter 8. + */ + this.flattenCharstring = function(aCharString, aDefaultWidth, aNominalWidth, aSubrs) { + var leftSidebearing = 0; + var lastPoint = 0; + while (true) { + var obj = nextInStack(); + if (IsBool(obj) || IsInt(obj) || IsNum(obj)) { + dump("Value: " + obj); + operandStack.push(obj); + } else if (IsString(obj)) { + dump("String: " + obj); + switch (obj) { + case "hsbw": + var charWidthVector = operandStack.pop(); + leftSidebearing = operandStack.pop(); + + if (charWidthVector != aDefaultWidth) + operandStack.push(charWidthVector - aNominalWidth); + break; + + case "setcurrentpoint": + case "dotsection": + case "seac": + case "sbw": + error(obj + " parsing is not implemented (yet)"); + break; + + case "vstem3": + operandStack.push("vstem"); + break; + + case "vstem": + log(obj + " is not converted (yet?)"); + operandStack.push("vstem"); + break; + + case "closepath": + case "return": + break; + + case "hlineto": + case "vlineto": + case "rlineto": + case "rrcurveto": + aggregateCommand(obj); + break; + + case "rmoveto": + var dy = operandStack.pop(); + var dx = operandStack.pop(); + + if (leftSidebearing) { + dx += leftSidebearing; + leftSidebearing = 0; + } + + operandStack.push(dx); + operandStack.push(dy); + operandStack.push("rmoveto"); + break; + + case "hstem": + case "hstem3": + var dy = operandStack.pop(); + var y = operandStack.pop(); + if (operandStack.peek() == "hstem" || + operandStack.peek() == "hstem3") + operandStack.pop(); + + operandStack.push(y - lastPoint); + lastPoint = y + dy; + + operandStack.push(dy); + operandStack.push("hstem"); + break; + + case "callsubr": + var index = operandStack.pop(); + executionStack.push(aSubrs[index].slice()); + break; + + case "callothersubr": + log("callothersubr"); + // XXX need to be improved + var index = operandStack.pop(); + var count = operandStack.pop(); + var data = operandStack.pop(); + operandStack.push(3); + operandStack.push("callothersubr"); + break; + case "endchar": + operandStack.push("endchar"); + return operandStack.__innerStack__.slice(); + case "pop": + operandStack.pop(); + break; + default: + operandStack.push(obj); + break; + } + } + } + } }; var type1hack = false; var Type1Font = function(aFontName, aFontFile) { + if (_Fonts[aFontName]) + return; + _Fonts[aFontName] = true; + // All Type1 font program should begin with the comment %! if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); if (!type1hack) { - type1hack= true; - var start = Date.now(); + type1hack = true; + var start = Date.now(); - var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); - var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); + var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); + var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); - this.parser = new Type1Parser(ASCIIStream, binaryStream); - this.parser.parse(); + this.parser = new Type1Parser(ASCIIStream, binaryStream); + var fontName = this.parser.parse(); + this.convertToOTF(fontName); + } +}; - var end = Date.now(); - //log("Time to parse font is:" + (end - start)); +Type1Font.prototype = { + convertToOTF: function(aFontName) { + var font = Fonts.get(aFontName); - this.convert(); + var private = font.get("Private"); + var subrs = private.get("Subrs"); + var otherSubrs = private.get("OtherSubrs"); + var charstrings = font.get("CharStrings") + + // Try to get the most used glyph width + var widths = {}; + for (var glyph in charstrings.map) { + var glyphData = charstrings.get(glyph); + var glyphWidth = glyphData[1]; + if (widths[glyphWidth]) + widths[glyphWidth]++; + else + widths[glyphWidth] = 1; + } + + var defaultWidth = 0; + var used = 0; + for (var width in widths) { + if (widths[width] > used) { + defaultWidth = width; + used = widths[width]; + } + } + log("defaultWidth to used: " + defaultWidth); + + var maxNegDistance = 0; + var maxPosDistance = 0; + for (var width in widths) { + var diff = width - defaultWidth; + if (diff < 0 && diff < maxNegDistance) { + maxNegDistance = diff; + } else if (diff > 0 && diff > maxPosDistance) { + maxPosDistance = diff; + } + } + + var nominalWidth = parseInt(defaultWidth) + (parseInt(maxPosDistance) + parseInt(maxNegDistance)) / 2; + log("nominalWidth to used: " + nominalWidth); + log("Hack nonimal:" + (nominalWidth = 615)); + + for (var glyph in charstrings.map) { + if (glyph == ".notdef") + continue; + + var glyphData = charstrings.get(glyph); + var parser = new Type1Parser(glyphData); + log("=================================== " + glyph + " =============================="); + log(charstrings.get(glyph)); + log(parser.flattenCharstring("A", defaultWidth, nominalWidth, subrs)); + log(validationData[glyph]); + } + + + /* + log(charStrings.get("A")); + log(newCharStrings.get("A")); + log(validationData["A"]); + */ + var end = Date.now(); + //log("Time to parse font is:" + (end - start)); } }; @@ -1016,6 +1309,7 @@ var Type2Parser = function(aFilePath) { // XXX +/* var xhr = new XMLHttpRequest(); xhr.open("GET", "titi.cff", false); xhr.mozResponseType = xhr.responseType = "arraybuffer"; @@ -1025,4 +1319,4 @@ var cffData = xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response; var cff = new Type2Parser("titi.cff"); cff.parse(new Stream(cffData)); - +*/ diff --git a/pdf.js b/pdf.js index ea6a62f57..ef8a18861 100644 --- a/pdf.js +++ b/pdf.js @@ -2280,9 +2280,9 @@ var CanvasGraphics = (function() { var subtype = font.get("Subtype").name; switch (subtype) { case "Type1": - break; var fontDescriptor = font.get("FontDescriptor"); if (fontDescriptor.num) { + // XXX fetchIfRef looks expensive var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); font = new Type1Font(fontDescriptor.get("FontName").name, fontFile); diff --git a/test.html b/test.html index 5bd0ea119..83d48741e 100644 --- a/test.html +++ b/test.html @@ -6,6 +6,7 @@ + From 3834c9be08096c98fe229d58a5e3faa2a0d3368d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 02:07:41 +0200 Subject: [PATCH 16/77] Move the Type2 utils to a new file and create a Stack object --- PDFFont.js | 630 ++++++++---------------------------------------- PDFFontUtils.js | 352 +++++++++++++++++++++++++++ 2 files changed, 457 insertions(+), 525 deletions(-) create mode 100644 PDFFontUtils.js diff --git a/PDFFont.js b/PDFFont.js index 5685e6874..407dd8b10 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -11,6 +11,47 @@ var Fonts = new Dict(); var _Fonts = {}; +var Stack = function() { + var innerStack = []; + + this.push = function(aOperand) { + innerStack.push(aOperand); + }; + + this.pop = function() { + if (!this.count()) + throw new Error("stackunderflow"); + return innerStack.pop(); + }; + + this.peek = function() { + if (!this.count()) + return null; + return innerStack[innerStack.length - 1]; + }; + + this.get = function(aIndex) { + return innerStack[aIndex]; + }; + + this.clear = function() { + innerStack = []; + }; + + this.count = function() { + return innerStack.length; + }; + + this.dump = function() { + for (var i = 0; i < this.length; i++) + log(innerStack[i]); + }; + + this.clone = function() { + return innerStack.slice(); + }; +}; + var Base64Encoder = { encode: function(aData) { var str = []; @@ -36,20 +77,8 @@ var TrueTypeFont = function(aFontName, aFontFile) { document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); }; - - - var Type1Parser = function(aAsciiStream, aBinaryStream) { - if (IsStream(aAsciiStream)) { - var lexer = new Lexer(aAsciiStream); - } else { - var lexer = { - __data__: aAsciiStream.slice(), - getObj: function() { - return this.__data__.shift(); - } - } - } + var lexer = aAsciiStream ? new Lexer(aAsciiStream) : null; // Turn on this flag for additional debugging logs var debug = false; @@ -225,41 +254,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * operator returns one or more results, it does so by pushing them on the * operand stack. */ - var operandStack = { - __innerStack__: [], - - push: function(aOperand) { - this.__innerStack__.push(aOperand); - }, - - pop: function() { - if (!this.length) - throw new Error("stackunderflow"); - return this.__innerStack__.pop(); - }, - - peek: function() { - if (!this.length) - return null; - return this.__innerStack__[this.__innerStack__.length - 1]; - }, - - get: function(aIndex) { - return this.__innerStack__[aIndex]; - }, - - dump: function() { - log("=== Start Dumping operandStack ==="); - var str = []; - for (var i = 0; i < this.length; i++) - log(this.__innerStack__[i]); - log("=== End Dumping operandStack ==="); - }, - - get length() { - return this.__innerStack__.length; - } - }; + var operandStack = new Stack(); // Flag indicating if the topmost operand of the operandStack is an array var operandIsArray = 0; @@ -277,42 +272,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { globalDict = new Dict(), userDict = new Dict(); - var dictionaryStack = { - __innerStack__: [systemDict, globalDict, userDict], - - push: function(aDictionary) { - this.__innerStack__.push(aDictionary); - }, - - pop: function() { - if (this.__innerStack__.length == 3) - return null; - - return this.__innerStack__.pop(); - }, - - peek: function() { - if (!this.length) - return null; - return this.__innerStack__[this.__innerStack__.length - 1]; - }, - - get: function(aIndex) { - return this.__innerStack__[aIndex]; - }, - - get length() { - return this.__innerStack__.length; - }, - - dump: function() { - log("=== Start Dumping dictionaryStack ==="); - var str = []; - for (var i = 0; i < this.length; i++) - log(this.__innerStack__[i]); - log("=== End Dumping dictionaryStack ==="); - }, - }; + var dictionaryStack = new Stack(); + dictionaryStack.push(systemDict); + dictionaryStack.push(globalDict); + dictionaryStack.push(userDict); /* * The execution stack holds executable objects (mainly procedures and files) @@ -324,31 +287,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * object off the execution stack and resumes executing the suspended object * beneath it. */ - var executionStack = { - __innerStack__: [], - - push: function(aProcedure) { - this.__innerStack__.push(aProcedure); - }, - - pop: function() { - return this.__innerStack__.pop(); - }, - - peek: function() { - if (!this.length) - return null; - return this.__innerStack__[this.__innerStack__.length - 1]; - }, - - get: function(aIndex) { - return this.__innerStack__[aIndex]; - }, - - get length() { - return this.__innerStack__.length; - } - }; + var executionStack = new Stack(); /* * Return the next token in the execution stack @@ -637,7 +576,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { default: var command = null; if (IsCmd(obj)) { - for (var i = 0; i < dictionaryStack.length; i++) { + for (var i = 0; i < dictionaryStack.count(); i++) { if (command = dictionaryStack.get(i).get(obj.cmd)) { dump("found in dictionnary for " + obj.cmd + " command: " + command); executionStack.push(command.slice()); @@ -760,7 +699,11 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * as descrived in 'Using Subroutines' of 'Adobe Type 1 Font Format', * chapter 8. */ - this.flattenCharstring = function(aCharString, aDefaultWidth, aNominalWidth, aSubrs) { + this.flattenCharstring = function(aCharstring, aDefaultWidth, aNominalWidth, aSubrs) { + operandStack.clear(); + executionStack.clear(); + executionStack.push(aCharstring); + var leftSidebearing = 0; var lastPoint = 0; while (true) { @@ -791,7 +734,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { break; case "vstem": - log(obj + " is not converted (yet?)"); + //log(obj + " is not converted (yet?)"); operandStack.push("vstem"); break; @@ -841,20 +784,24 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { break; case "callothersubr": - log("callothersubr"); // XXX need to be improved var index = operandStack.pop(); var count = operandStack.pop(); var data = operandStack.pop(); + if (index != 3) + log("callothersubr for index: " + index); operandStack.push(3); operandStack.push("callothersubr"); break; + case "endchar": operandStack.push("endchar"); - return operandStack.__innerStack__.slice(); + return operandStack.clone(); + case "pop": operandStack.pop(); break; + default: operandStack.push(obj); break; @@ -885,41 +832,31 @@ var Type1Font = function(aFontName, aFontFile) { this.parser = new Type1Parser(ASCIIStream, binaryStream); var fontName = this.parser.parse(); this.convertToOTF(fontName); + var end = Date.now(); + log("Time to parse font is:" + (end - start)); } }; Type1Font.prototype = { - convertToOTF: function(aFontName) { - var font = Fonts.get(aFontName); - - var private = font.get("Private"); - var subrs = private.get("Subrs"); - var otherSubrs = private.get("OtherSubrs"); - var charstrings = font.get("CharStrings") - - // Try to get the most used glyph width - var widths = {}; - for (var glyph in charstrings.map) { - var glyphData = charstrings.get(glyph); - var glyphWidth = glyphData[1]; - if (widths[glyphWidth]) - widths[glyphWidth]++; - else - widths[glyphWidth] = 1; - } - + getDefaultWidths: function(aCharstrings) { var defaultWidth = 0; - var used = 0; - for (var width in widths) { - if (widths[width] > used) { - defaultWidth = width; - used = widths[width]; - } - } - log("defaultWidth to used: " + defaultWidth); + var defaultUsedCount = 0; - var maxNegDistance = 0; - var maxPosDistance = 0; + var widths = {}; + for (var glyph in aCharstrings.map) { + var width = aCharstrings.get(glyph)[1]; + var usedCount = (widths[width] || 0) + 1; + + if (usedCount > defaultUsedCount) { + defaultUsedCount = usedCount; + defaultWidth = width; + } + + widths[width] = usedCount; + } + defaultWidth = parseInt(defaultWidth); + + var maxNegDistance = 0, maxPosDistance = 0; for (var width in widths) { var diff = width - defaultWidth; if (diff < 0 && diff < maxNegDistance) { @@ -929,394 +866,37 @@ Type1Font.prototype = { } } - var nominalWidth = parseInt(defaultWidth) + (parseInt(maxPosDistance) + parseInt(maxNegDistance)) / 2; + return { + default: defaultWidth, + nominal: defaultWidth + (maxPosDistance + maxNegDistance) / 2 + }; + }, + + convertToOTF: function(aFontName) { + var font = Fonts.get(aFontName); + + var charstrings = font.get("CharStrings") + var defaultWidths = this.getDefaultWidths(charstrings); + var defaultWidth = defaultWidths.default; + var nominalWidth = defaultWidths.nominal; + + log("defaultWidth to used: " + defaultWidth); log("nominalWidth to used: " + nominalWidth); log("Hack nonimal:" + (nominalWidth = 615)); + + var glyphs = {}; + var subrs = font.get("Private").get("Subrs"); + var parser = new Type1Parser(); for (var glyph in charstrings.map) { - if (glyph == ".notdef") - continue; + var charstring = charstrings.get(glyph); + glyphs[glyph] = parser.flattenCharstring(charstring, defaultWidth, nominalWidth, subrs); - var glyphData = charstrings.get(glyph); - var parser = new Type1Parser(glyphData); - log("=================================== " + glyph + " =============================="); - log(charstrings.get(glyph)); - log(parser.flattenCharstring("A", defaultWidth, nominalWidth, subrs)); - log(validationData[glyph]); + //log("=================================== " + glyph + " =============================="); + //log(charstrings.get(glyph)); + //log(flattenedCharstring); + //log(validationData[glyph]); } - - - /* - log(charStrings.get("A")); - log(newCharStrings.get("A")); - log(validationData["A"]); - */ - var end = Date.now(); - //log("Time to parse font is:" + (end - start)); } }; - - - - - - - - - - - - -/** - * 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. - */ - - -/** - * 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(); - - // Turn on this flag for additional debugging logs - var debug = true; - - function dump(aStr) { - if (debug) - log(aStr); - }; - - function parseAsToken(aString, aMap) { - var decoded = readFontDictData(aString, aMap); - log(decoded); - - 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)); - - // Read the Top Dict Index - dump("Reading Index: TopDict"); - var topDict = readFontIndexData(aStream, true); - - // Read the String Index - dump("Reading Index: Strings"); - var strings = readFontIndexData(aStream); - - // 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); - - // 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()); - 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); - - - var charsetEntry = font.get("charset"); - if (charsetEntry == 0) { - throw new Error("Need to support CFFISOAdobeCharset"); - } else if (charsetEntry == 1) { - throw new Error("Need to support CFFExpert"); - } else if (charsetEntry == 2) { - throw new Error("Need to support CFFExpertSubsetCharset"); - } else { - aStream.pos = charsetEntry; - var charset = readCharset(aStream, charStrings); - } - - } -}; - - -// XXX -/* -var xhr = new XMLHttpRequest(); -xhr.open("GET", "titi.cff", false); -xhr.mozResponseType = xhr.responseType = "arraybuffer"; -xhr.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200; -xhr.send(null); -var cffData = xhr.mozResponseArrayBuffer || xhr.mozResponse || - xhr.responseArrayBuffer || xhr.response; -var cff = new Type2Parser("titi.cff"); -cff.parse(new Stream(cffData)); -*/ diff --git a/PDFFontUtils.js b/PDFFontUtils.js new file mode 100644 index 000000000..3ae87f4ab --- /dev/null +++ b/PDFFontUtils.js @@ -0,0 +1,352 @@ +/** + * 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. + */ + + +/** + * 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(); + + // Turn on this flag for additional debugging logs + var debug = true; + + function dump(aStr) { + if (debug) + log(aStr); + }; + + function parseAsToken(aString, aMap) { + var decoded = readFontDictData(aString, aMap); + log(decoded); + + 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)); + + // Read the Top Dict Index + dump("Reading Index: TopDict"); + var topDict = readFontIndexData(aStream, true); + + // Read the String Index + dump("Reading Index: Strings"); + var strings = readFontIndexData(aStream); + + // 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); + + // 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()); + 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); + + + var charsetEntry = font.get("charset"); + if (charsetEntry == 0) { + throw new Error("Need to support CFFISOAdobeCharset"); + } else if (charsetEntry == 1) { + throw new Error("Need to support CFFExpert"); + } else if (charsetEntry == 2) { + throw new Error("Need to support CFFExpertSubsetCharset"); + } else { + aStream.pos = charsetEntry; + var charset = readCharset(aStream, charStrings); + } + + } +}; + + +// XXX +/* +var xhr = new XMLHttpRequest(); +xhr.open("GET", "titi.cff", false); +xhr.mozResponseType = xhr.responseType = "arraybuffer"; +xhr.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200; +xhr.send(null); +var cffData = xhr.mozResponseArrayBuffer || xhr.mozResponse || + xhr.responseArrayBuffer || xhr.response; +var cff = new Type2Parser("titi.cff"); +cff.parse(new Stream(cffData)); +*/ From 18b2e3c6f874b850e3e8974df43c2df8dcba43e6 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 06:12:59 +0200 Subject: [PATCH 17/77] Add the beginning of a CFF encoder --- PDFFont.js | 209 +++++++++++++++++++++++++++++++++++++++++++++++- PDFFontUtils.js | 19 ++--- t2data.js | 60 ++++++++++++++ test.html | 1 + 4 files changed, 279 insertions(+), 10 deletions(-) create mode 100644 t2data.js diff --git a/PDFFont.js b/PDFFont.js index 407dd8b10..c001c825e 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -57,7 +57,7 @@ var Base64Encoder = { var str = []; var count = aData.length; for (var i = 0; i < count; i++) - str.push(aData.getChar()); + str.push(aData.getChar ? aData.getChar : String.fromCharCode(aData[i])); return window.btoa(str.join("")); } @@ -897,6 +897,213 @@ Type1Font.prototype = { //log(flattenedCharstring); //log(validationData[glyph]); } + + // Create a CFF font data + var cff = new Uint8Array(20000); + 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([aFontName]); + cff.set(nameIndex, currentOffset); + currentOffset += nameIndex.length; + + //Top Dict Index + var topDictIndex = [ + 0x00, 0x01, 0x01, 0x01, 0x29, + 248, 27, 0, // version + 248, 28, 1, // Notice + 248, 29, 2, // FullName + 248, 30, 3, // FamilyName + 248, 20, 4, // Weigth + 82, 251, 98, 250, 105, 249, 72, 5, // FontBBox + 248, 136, 15, // charset (offset: 500) + 28, 0, 0, 16, // Encoding (offset: 600) + 248, 236, 17, // CharStrings + 28, 0, 55, 28, 15, 160, 18 // Private (offset: 4000) + ]; + cff.set(topDictIndex, currentOffset); + currentOffset += topDictIndex.length; + + // Strings Index + var stringsIndex = [ + 0x00, 0x04, 0x01, + 0x01, 0x05, 0x06, 0x07, 0x08, + 0x31, 0x2E, 0x030, 0x35, // 1.05 + 0x2B, // + + 0x28, // ( + 0x29 // ) + ]; + cff.set(stringsIndex, currentOffset); + currentOffset += stringsIndex.length; + + + // Global Subrs Index + var globalSubrsIndex = [ + 0x00, 0x00, 0x00 + ]; + cff.set(globalSubrsIndex, currentOffset); + currentOffset += globalSubrsIndex.length; + + // Fill the space between this and the charset by '1' + var empty = new Array(500 - currentOffset); + for (var i = 0; i < empty.length; i++) + empty[i] = 0x01; + cff.set(empty, currentOffset); + currentOffset += empty.length; + + //Declare the letter 'C' + var charset = [ + 0x00, 0x00, 0x42 + ]; + cff.set(charset, currentOffset); + currentOffset += charset.length; + + // Fill the space between this and the charstrings data by '1' + var empty = new Array(600 - currentOffset); + for (var i = 0; i < empty.length; i++) + empty[i] = 0x01; + cff.set(empty, currentOffset); + currentOffset += empty.length; + + + // Encode the glyph and add it to the FUX + var charStringsIndex = [ + 0x00, 0x02, 0x01, 0x01, 0x03, 0x05, + 0x40, 0x0E, + 0xAF, 0x0E + ]; + cff.set(charStringsIndex, currentOffset); + currentOffset += charStringsIndex.length; + + // Fill the space between this and the private dict data by '1' + var empty = new Array(4000 - currentOffset); + for (var i = 0; i < empty.length; i++) + empty[i] = 0x01; + cff.set(empty, currentOffset); + currentOffset += empty.length; + + // Private Data + var privateData = [ + 248, 136, 20, + 248, 251, 21, + 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 + ]; + 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 file = new Uint8Array(cff, 0, currentOffset); + var parser = new Type2Parser(); + parser.parse(new Stream(file)); + + var file64 = Base64Encoder.encode(file); + console.log(file64); + + var data = []; + for (var i = 0; i < currentOffset; i++) + data.push(cff[i]); + log(data); + }, + + createCFFIndexHeader: function(aObjects, aIsByte) { + var data = []; + + // First 2 bytes contains the number of objects contained into this index + var count = aObjects.length; + var bytes = 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 = 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][j].charCodeAt(0)); + } + return data; } }; +function integerToBytes(aValue, aBytesCount) { + var bytes = []; + + do { + bytes[--aBytesCount] = (aValue & 0xFF); + aValue = aValue >> 8; + } while (aBytesCount && aValue > 0); + + return bytes; +}; + +function encodeNumber(aValue) { + var x = 0; + if (aValue >= -107 && aValue <= 107) { + return [aValue + 139]; + } else if (aValue >= 108 && aValue <= 1131) { + x = aValue - 108; + return [ + integerToBytes(x / 256 + 247, 1), + x % 256 + ]; + } else if (aValue >= -1131 && aValue <= -108) { + x = Math.abs(aValue) - 108; + return [ + integerToBytes(x / 256 + 251, 1), + x % 256 + ]; + } else if (aValue >= -32768 && aValue <= 32767) { + return [ + 28, + integerToBytes(aValue >> 8, 1), + integerToBytes(aValue, 1) + ]; + } else if (aValue >= (-2147483647-1) && aValue <= 2147483647) { + return [ + 0xFF, + integerToBytes(aValue >> 24, 1), + integerToBytes(aValue >> 16, 1), + integerToBytes(aValue >> 8, 1), + integerToBytes(aValue, 1) + ]; + } else { + error("Value: " + aValue + " is not allowed"); + } +} diff --git a/PDFFontUtils.js b/PDFFontUtils.js index 3ae87f4ab..02c588217 100644 --- a/PDFFontUtils.js +++ b/PDFFontUtils.js @@ -22,6 +22,7 @@ function readCharset(aStream, aCharstrings) { var count = aCharstrings.length - 1; for (var i = 1; i < count + 1; i++) { var sid = aStream.getByte() << 8 | aStream.getByte(); + log(sid); charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]); log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]); } @@ -282,10 +283,12 @@ var Type2Parser = function(aFilePath) { // Read the Top Dict Index dump("Reading Index: TopDict"); var topDict = readFontIndexData(aStream, true); + log(topDict); // Read the String Index dump("Reading Index: Strings"); var strings = readFontIndexData(aStream); + log(strings); // Fill up the Strings dictionary with the new unique strings for (var i = 0; i < strings.length; i++) @@ -310,6 +313,7 @@ var Type2Parser = function(aFilePath) { 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) @@ -321,25 +325,23 @@ var Type2Parser = function(aFilePath) { 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) { - throw new Error("Need to support CFFISOAdobeCharset"); + error("Need to support CFFISOAdobeCharset"); } else if (charsetEntry == 1) { - throw new Error("Need to support CFFExpert"); + error("Need to support CFFExpert"); } else if (charsetEntry == 2) { - throw new Error("Need to support CFFExpertSubsetCharset"); + error("Need to support CFFExpertSubsetCharset"); } else { aStream.pos = charsetEntry; var charset = readCharset(aStream, charStrings); } - } }; -// XXX -/* var xhr = new XMLHttpRequest(); xhr.open("GET", "titi.cff", false); xhr.mozResponseType = xhr.responseType = "arraybuffer"; @@ -348,5 +350,4 @@ xhr.send(null); var cffData = xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response; var cff = new Type2Parser("titi.cff"); -cff.parse(new Stream(cffData)); -*/ +//cff.parse(new Stream(cffData)); diff --git a/t2data.js b/t2data.js new file mode 100644 index 000000000..6e5f52344 --- /dev/null +++ b/t2data.js @@ -0,0 +1,60 @@ +var validationData = { +hyphen: ["-282","171","116","hstem","44","243","vstem","287","287","rmoveto","-243","-116","243","hlineto","endchar"], +period: ["-365","-13","20","hstem","125","156","rmoveto","-107","callsubr","endchar"], +zero: ["-13","28","645","28","hstem","24","158","136","158","vstem","250","688","rmoveto","-65","0","-66","-44","-41","-72","-32","-55","-22","-94","0","-83","rrcurveto","-206","94","-147","133","129","96","149","201","200","-97","151","-129","vhcurveto","68","-466","rmoveto","0","-59","-8","-78","-9","-27","-11","-29","-16","-14","-23","0","rrcurveto","-50","-19","59","148","hvcurveto","229","vlineto","151","19","58","48","49","20","-62","-147","vhcurveto","endchar"], +one: ["0","24","529","26","89","20","hstem","186","148","vstem","317","688","rmoveto","-252","-109","0","-26","rlineto","9","3","8","3","3","2","27","10","25","7","13","0","rrcurveto","25","11","-22","-47","hvcurveto","-385","vlineto","0","-82","-20","-17","-99","-1","rrcurveto","-24","375","24","vlineto","-91","2","-17","15","0","77","rrcurveto","570","vlineto","endchar"], +two: ["0","133","441","114","hstem","300","136","vstem","478","211","rmoveto","-24","hlineto","-29","-72","-12","-6","-102","0","rrcurveto","-151","0","162","154","rlineto","79","75","35","67","0","76","0","107","-77","76","-108","0","-50","0","-48","-20","-35","-36","-39","-39","-20","-34","-28","-75","rrcurveto","28","hlineto","31","62","37","28","54","0","44","0","33","-19","22","-36","12","-21","8","-28","0","-23","0","-44","-19","-55","-32","-49","-51","-78","-35","-42","-146","-156","rrcurveto","-23","416","vlineto","endchar"], +three: ["-14","50","571","81","hstemhm","283","146","-75","114","hintmask","58","523","rmoveto","38","61","33","23","52","0","63","0","39","-40","0","-63","0","-66","-35","-35","-95","-30","rrcurveto","-17","vlineto","83","-29","33","-17","36","-34","rrcurveto","hintmask","31","-29","18","-45","0","-48","0","-72","-38","-46","-60","0","-24","0","-19","11","-33","32","-39","39","-30","16","-30","0","rrcurveto","-38","-27","-24","-34","-54","61","-36","92","167","132","114","146","hvcurveto","0","46","-15","43","-29","35","-21","24","-17","12","-40","18","rrcurveto","hintmask","64","39","19","29","0","59","0","86","-61","51","-102","0","-99","0","-75","-50","-55","-103","rrcurveto","endchar"], +four: ["0","20","124","111","413","20","hstemhm","267","145","-143","143","hintmask","412","255","rmoveto","433","-80","vlineto","-59","-77","rlineto","-128","-167","-66","-92","-60","-95","rrcurveto","-113","248","-144","vlineto","hintmask","145","144","63","111","hlineto","-206","hmoveto","-209","0","209","297","rlineto","endchar"], +five: ["-8","61","496","127","hstem","373","78","vstem","149","549","rmoveto","278","0","43","127","-322","0","-97","-345","rlineto","95","-7","41","-6","44","-14","89","-28","53","-57","0","-66","0","-56","-44","-44","-56","0","-23","0","-27","12","-40","30","-43","32","-30","13","-26","0","rrcurveto","-36","-26","-25","-35","-53","58","-35","89","165","117","100","141","hvcurveto","0","104","-64","80","-109","31","-38","11","-31","4","-82","5","rrcurveto","endchar"], +six: ["-13","27","362","45","247","20","hstem","28","156","139","152","vstem","470","688","rmoveto","-133","-19","-62","-22","-76","-52","-112","-77","-59","-112","0","-133","rrcurveto","-173","92","-113","140","124","91","99","136","121","-73","78","-114","vhcurveto","-32","0","-22","-4","-30","-13","37","147","83","81","146","30","rrcurveto","-237","-286","rmoveto","67","23","-55","-159","-118","-12","-30","-49","hvcurveto","-23","0","-18","10","-10","19","-17","33","-10","73","0","93","0","62","6","57","7","5","8","6","14","4","14","0","rrcurveto","endchar"], +seven: ["0","20","519","137","hstem","477","676","rmoveto","-416","0","-44","-222","25","0","rlineto","19","64","24","21","55","0","rrcurveto","207","0","-200","-539","95","0","rlineto","endchar"], +eight: ["-13","32","640","29","hstemhm","28","121","-110","129","165","139","-133","119","hintmask","178","324","rmoveto","-57","-19","-23","-13","-26","-25","-29","-28","-15","-38","0","-44","rrcurveto","-102","85","-68","127","139","93","80","120","vhcurveto","0","87","-43","62","-107","68","rrcurveto","hintmask","96","34","40","41","0","64","rrcurveto","89","-76","56","-119","-135","-89","-70","-105","vhcurveto","0","-75","40","-55","99","-59","rrcurveto","120","98","rmoveto","-84","43","-46","55","0","56","rrcurveto","47","36","36","47","56","32","-45","-78","vhcurveto","0","-47","-8","-23","-33","-44","rrcurveto","hintmask","-98","-116","rmoveto","109","-73","24","-32","0","-74","rrcurveto","-67","-33","-41","-54","-61","-36","53","89","vhcurveto","0","55","11","31","40","59","rrcurveto","endchar"], +nine: ["-13","20","247","45","362","27","hstem","26","152","139","156","vstem","31","-13","rmoveto","140","20","68","25","78","59","102","77","54","107","0","127","rrcurveto","173","-92","113","-140","-125","-90","-99","-137","-118","73","-80","109","vhcurveto","38","0","26","5","27","14","-43","-152","-81","-79","-144","-29","rrcurveto","278","315","rmoveto","-1","-13","-1","-5","-3","-2","-7","-5","-19","-4","-15","0","rrcurveto","-62","-23","59","157","116","12","30","49","hvcurveto","25","0","17","-11","11","-23","15","-28","10","-70","0","-71","0","-27","-2","-32","-3","-45","rrcurveto","endchar"], +colon: ["-282","-13","169","147","169","hstem","166","156","rmoveto","-107","callsubr","316","vmoveto","-46","-38","-38","-45","-49","36","-37","48","47","38","38","46","47","-38","38","-47","hvcurveto","endchar"], +equal: ["-45","107","88","116","88","hstem","537","399","rmoveto","-504","-88","504","hlineto","-116","vmoveto","-504","-88","504","hlineto","endchar"], +A: ["107","0","25","172","39","223","20","191","20","hstem","689","25","rmoveto","-4","hlineto","-39","0","-16","21","-50","118","rrcurveto","-223","526","-28","0","-222","-548","rlineto","-38","-93","-12","-15","-48","-9","rrcurveto","-25","203","25","vlineto","-59","4","-23","11","0","26","0","13","8","25","21","54","rrcurveto","15","39","225","0","rlineto","34","-78","12","-36","0","-22","0","-21","-13","-10","-35","-2","-5","0","-13","-1","-14","-2","rrcurveto","-25","324","vlineto","-500","236","rmoveto","94","243","101","-243","rlineto","endchar"], +B: ["52","0","25","-25","32","614","30","-25","25","hstemhm","104","160","156","165","-138","172","hintmask","16","676","rmoveto","hintmask","-25","vlineto","69","-4","19","-16","0","-51","rrcurveto","-484","vlineto","0","-51","-15","-12","-73","-8","rrcurveto","hintmask","-25","322","vlineto","169","112","75","113","hvcurveto","0","45","-19","41","-35","31","-35","30","-34","15","-70","15","rrcurveto","hintmask","116","34","43","41","0","76","rrcurveto","103","-93","57","-167","vhcurveto","-61","-333","rmoveto","30","hlineto","hintmask","103","50","-54","-110","-97","-41","-50","-81","-44","-17","17","44","hvcurveto","504","vmoveto","36","15","13","39","vhcurveto","hintmask","70","32","-43","-94","hvcurveto","0","-105","-33","-28","-123","-3","rrcurveto","endchar"], +C: ["107","-19","48","629","33","hstem","49","177","vstem","657","152","rmoveto","-59","-62","-32","-24","-49","-19","-29","-12","-33","-6","-28","0","-66","0","-63","35","-29","52","-29","53","-14","72","0","100","0","207","64","110","120","0","47","0","43","-18","43","-38","rrcurveto","43","-39","23","-33","35","-76","rrcurveto","25","234","-27","hlineto","-14","-35","-11","-11","-19","0","-9","0","-15","4","-22","10","-59","24","-48","11","-48","0","rrcurveto","-199","-149","-154","-204","-206","147","-146","207","hvcurveto","71","0","59","17","55","37","32","22","22","20","45","50","rrcurveto","endchar"], +D: ["107","0","25","-25","35","607","34","-25","25","hstemhm","97","162","257","174","hintmask","97","91","rmoveto","0","-44","-25","-20","-58","-2","rrcurveto","hintmask","-25","316","vlineto","216","144","138","207","206","-140","125","-231","hvcurveto","-305","hlineto","hintmask","-25","vlineto","64","-6","19","-15","0","-46","rrcurveto","hintmask","162","23","rmoveto","23","20","12","39","vhcurveto","72","0","51","-33","34","-69","27","-53","14","-73","0","-84","0","-95","-20","-86","-32","-45","-34","-46","-48","-23","-65","0","rrcurveto","-45","-13","13","45","hvcurveto","endchar"], +E: ["52","0","25","-25","31","611","34","-25","25","hstemhm","104","162","hintmask","593","676","rmoveto","-577","hlineto","hintmask","-25","vlineto","69","-4","19","-16","0","-51","rrcurveto","-484","vlineto","0","-52","-14","-11","-74","-8","rrcurveto","hintmask","-25","585","vlineto","40","208","-28","0","rlineto","-31","-67","-20","-28","-36","-29","-46","-37","-55","-16","-76","0","rrcurveto","-64","-19","13","43","hvcurveto","242","vlineto","109","0","41","-39","12","-116","rrcurveto","26","338","-26","hlineto","-15","-114","-39","-36","-108","1","rrcurveto","232","vlineto","38","13","9","52","vhcurveto","163","0","49","-34","25","-133","rrcurveto","25","hlineto","endchar"], +F: ["-4","0","25","617","34","-25","25","hstemhm","104","162","hintmask","583","676","rmoveto","-567","hlineto","hintmask","-25","vlineto","69","-4","19","-15","0","-52","rrcurveto","-484","vlineto","0","-52","-14","-11","-74","-8","rrcurveto","-25","360","25","vlineto","-92","4","-18","12","0","55","rrcurveto","233","vlineto","102","-2","37","-37","14","-116","rrcurveto","25","338","-25","hlineto","-18","-114","-35","-35","-100","0","rrcurveto","232","vlineto","hintmask","37","13","10","51","vhcurveto","92","0","59","-17","31","-35","22","-25","11","-27","14","-63","rrcurveto","24","hlineto","endchar"], +G: ["163","-19","33","644","33","hstem","37","177","299","156","vstem","755","287","rmoveto","-343","-25","hlineto","86","-5","15","-11","0","-54","rrcurveto","-105","vlineto","-51","-29","-22","-67","vhcurveto","-63","0","-42","19","-33","43","-44","56","-21","86","0","120","0","209","63","111","121","0","46","0","43","-18","44","-38","43","-38","23","-34","35","-76","rrcurveto","25","234","-27","hlineto","-14","-35","-11","-11","-19","0","-9","0","-15","4","-22","10","-59","24","-48","11","-48","0","rrcurveto","-199","-149","-154","-206","-206","146","-144","210","hvcurveto","103","0","109","24","64","38","rrcurveto","127","vlineto","0","72","11","12","75","8","rrcurveto","endchar"], +I: ["-226","0","25","626","25","hstem","113","162","vstem","113","96","rmoveto","0","-50","-18","-14","-75","-7","rrcurveto","-25","350","25","vlineto","-76","5","-19","14","0","52","rrcurveto","484","vlineto","0","52","21","16","74","3","rrcurveto","25","-350","-25","vlineto","72","-5","21","-15","0","-51","rrcurveto","endchar"], +J: ["-96","33","714","25","hstem","3","116","109","162","vstem","390","559","rmoveto","0","72","14","15","75","5","rrcurveto","25","-352","-25","vlineto","81","-3","20","-14","0","-54","rrcurveto","-556","vlineto","-62","-19","-25","-45","-27","-18","13","19","vhcurveto","0","8","3","6","9","12","12","15","3","8","0","15","rrcurveto","40","-34","35","-39","-37","-33","-34","-38","vhcurveto","0","-41","28","-45","39","-23","26","-14","40","-9","40","0","rrcurveto","140","74","76","143","hvcurveto","endchar"], +L: ["52","0","25","-25","31","620","25","hstemhm","105","162","hintmask","638","227","rmoveto","-29","hlineto","-33","-78","-20","-31","-35","-32","-41","-37","-56","-18","-77","0","rrcurveto","-61","-19","13","43","hvcurveto","472","vlineto","0","75","14","13","87","4","rrcurveto","25","-349","-25","vlineto","68","-4","18","-16","0","-51","rrcurveto","-484","vlineto","hintmask","0","-51","-13","-11","-73","-9","rrcurveto","hintmask","-25","578","vlineto","endchar"], +M: ["329","0","25","626","25","hstem","105","42","531","155","vstem","678","609","rmoveto","-509","vlineto","0","-56","-14","-12","-75","-7","rrcurveto","-25","332","25","vlineto","-78","10","-10","11","0","71","rrcurveto","442","vlineto","0","72","15","15","73","5","rrcurveto","25","-252","vlineto","-200","-472","-200","472","-253","0","0","-25","rlineto","73","-6","16","-13","0","-52","rrcurveto","-475","vlineto","0","-60","-13","-12","-78","-8","rrcurveto","-25","234","25","vlineto","-82","6","-19","19","0","74","rrcurveto","0","470","252","-594","27","0","rlineto","endchar"], +N: ["107","-18","20","-2","25","626","25","hstemhm","104","44","431","44","hintmask","230","676","rmoveto","-211","-25","hlineto","20","0","17","-15","48","-57","rrcurveto","-474","vlineto","0","-57","-15","-14","-73","-9","rrcurveto","-25","227","25","vlineto","-77","9","-18","19","0","71","rrcurveto","0","402","rlineto","hintmask","447","-544","28","0","0","589","rlineto","0","57","13","13","65","10","rrcurveto","25","-215","-25","vlineto","74","-7","19","-21","0","-71","rrcurveto","-305","vlineto","endchar"], +O: ["163","-19","33","644","33","hstem","35","177","354","177","vstem","393","691","rmoveto","-209","-149","-148","-208","-207","147","-147","207","207","147","148","207","204","-149","151","-201","hvcurveto","-1","-33","rmoveto","110","64","-121","-208","-205","-62","-110","-115","-115","-62","110","202","216","63","116","117","hvcurveto","endchar"], +P: ["-4","0","25","616","35","-25","25","hstemhm","100","162","166","172","hintmask","262","303","rmoveto","135","1","34","3","44","18","81","31","44","61","0","77","rrcurveto","116","-95","66","-167","vhcurveto","-322","hlineto","hintmask","-25","vlineto","70","-6","14","-16","0","-70","rrcurveto","-442","vlineto","0","-62","-13","-20","-47","-6","-3","0","-10","-2","-11","-2","rrcurveto","-25","334","25","vlineto","-79","10","-9","9","0","73","rrcurveto","hintmask","489","vmoveto","23","17","12","33","83","33","-44","-108","vhcurveto","0","-63","-12","-38","-26","-23","-24","-20","-33","-7","-71","0","rrcurveto","endchar"], +R: ["107","0","25","617","34","-25","25","hstemhm","114","162","183","171","hintmask","715","25","rmoveto","-18","0","-13","6","-10","13","rrcurveto","-201","285","rlineto","59","19","25","13","28","25","29","27","16","40","0","45","rrcurveto","115","-99","63","-183","vhcurveto","-322","hlineto","hintmask","-25","vlineto","74","-5","14","-15","0","-72","rrcurveto","-442","vlineto","0","-73","-10","-10","-78","-9","rrcurveto","-25","338","25","vlineto","-78","10","-10","11","0","71","rrcurveto","196","27","vlineto","207","-313","205","0","rlineto","hintmask","-439","600","rmoveto","0","6","4","15","3","6","6","10","16","5","25","0","92","0","37","-43","0","-105","0","-64","-15","-39","-32","-21","-26","-17","-34","-7","-76","-1","rrcurveto","endchar"], +S: ["-59","-19","33","646","31","-19","20","hstemhm","44","109","241","119","hintmask","484","475","rmoveto","217","-30","vlineto","-7","-26","-8","-8","-17","0","-9","0","-11","3","-22","8","rrcurveto","hintmask","-47","16","-32","6","-38","0","-136","0","-83","-77","0","-126","0","-88","52","-63","119","-57","rrcurveto","67","-32","rlineto","88","-42","24","-26","0","-52","0","-69","-49","-45","-77","0","-58","0","-50","25","-38","49","-27","37","-14","33","-17","70","rrcurveto","-29","-247","29","hlineto","6","25","8","9","16","0","8","0","11","-3","22","-7","50","-17","37","-7","43","0","148","0","100","85","0","126","0","75","-46","75","-64","32","rrcurveto","-147","73","rlineto","-81","40","-22","25","0","48","0","62","42","38","68","0","45","0","42","-19","36","-37","34","-35","16","-29","20","-65","rrcurveto","endchar"], +T: ["52","0","25","631","20","hstem","253","162","vstem","253","117","rmoveto","0","-74","-11","-11","-86","-7","rrcurveto","-25","357","25","vlineto","-87","6","-11","10","0","76","rrcurveto","527","vlineto","123","-4","52","-46","17","-119","rrcurveto","29","0","-2","201","-600","0","-3","-201","29","0","rlineto","17","119","52","46","124","4","rrcurveto","endchar"], +V: ["107","-18","20","654","20","hstem","701","676","rmoveto","-213","-25","hlineto","71","-5","15","-7","0","-32","0","-16","-3","-12","-17","-43","rrcurveto","-127","-329","-138","334","rlineto","-19","45","-4","12","0","15","0","23","15","11","38","2","5","0","13","1","15","1","rrcurveto","25","-336","-25","vlineto","50","-7","9","-8","25","-55","rrcurveto","256","-599","27","0","228","587","rlineto","24","62","14","13","52","7","rrcurveto","endchar"], +W: ["385","-15","20","437","20","194","20","hstem","981","676","rmoveto","-182","-25","hlineto","54","-3","15","-10","0","-31","0","-13","-2","-15","-5","-14","rrcurveto","-112","-343","-108","336","rlineto","-10","32","-4","15","0","9","0","24","15","9","44","3","2","0","5","0","6","1","rrcurveto","25","-312","-25","vlineto","41","-2","20","-9","11","-24","rrcurveto","35","-96","-118","-308","-120","364","rlineto","-5","16","-2","8","0","9","0","29","12","9","52","4","rrcurveto","25","-294","-25","vlineto","42","-6","10","-9","17","-49","rrcurveto","212","-602","28","0","186","477","171","-477","27","0","200","602","rlineto","13","40","23","21","33","3","rrcurveto","endchar"], +a: ["-14","20","435","32","hstemhm","25","146","122","138","-137","137","hintmask","473","64","rmoveto","-10","-10","rlineto","-3","-3","-3","-1","-5","0","rrcurveto","-14","-7","9","16","hvcurveto","261","vlineto","84","-76","53","-122","-113","-76","-51","-75","-41","24","-25","41","40","28","24","34","vhcurveto","0","14","-6","13","-12","16","-9","10","-3","6","0","6","rrcurveto","21","28","16","35","vhcurveto","hintmask","58","26","-27","-61","hvcurveto","-73","vlineto","-119","-36","-49","-20","-37","-25","-43","-30","-21","-34","0","-43","0","-61","47","-45","64","0","57","0","46","20","55","50","11","-51","22","-19","49","0","43","0","31","16","38","41","rrcurveto","hintmask","-195","57","rmoveto","-27","-31","-20","-12","-24","0","-30","0","-21","27","0","40","0","58","42","42","80","21","rrcurveto","endchar"], +b: ["-59","-14","32","401","54","179","24","hstem","72","139","163","147","vstem","211","676","rmoveto","-194","-24","hlineto","46","-9","9","-9","0","-40","rrcurveto","-607","12","vlineto","79","56","rlineto","46","-41","36","-16","50","0","rrcurveto","133","93","104","149","138","-77","96","-111","hvcurveto","-48","0","-37","-17","-37","-39","rrcurveto","-57","vmoveto","17","43","20","16","33","0","rrcurveto","62","31","-67","-131","-138","-30","-65","-64","-42","-27","31","48","hvcurveto","endchar"], +c: ["-171","-14","67","389","31","hstem","25","141","vstem","412","109","rmoveto","-37","-42","-26","-14","-41","0","rrcurveto","-87","-55","87","136","103","32","63","52","hvcurveto","16","0","15","-8","6","-11","5","-9","0","0","0","-42","1","-49","18","-23","37","0","rrcurveto","42","26","24","39","62","-67","48","-88","-136","-100","-106","-144","-138","90","-99","124","hvcurveto","77","0","56","31","58","74","rrcurveto","endchar"], +d: ["-59","-14","56","-22","23","374","56","179","24","hstemhm","25","148","163","139","hintmask","339","-13","rmoveto","46","13","25","5","62","7","rrcurveto","62","8","0","23","rlineto","-46","3","-13","13","0","42","rrcurveto","575","-215","-24","vlineto","67","-5","9","-7","0","-46","rrcurveto","-183","vlineto","-43","46","-30","16","-46","0","rrcurveto","-110","-82","-107","-145","hvcurveto","hintmask","-136","76","-99","105","vhcurveto","53","0","33","16","47","50","rrcurveto","-3","60","rmoveto","0","-6","-10","-17","-12","-13","-20","-23","-21","-11","-22","0","rrcurveto","-53","-25","60","127","129","27","59","58","hvcurveto","33","0","31","-24","14","-38","rrcurveto","endchar"], +e: ["-171","-14","72","187","37","160","31","hstem","402","125","rmoveto","-40","-49","-31","-18","-43","0","-39","0","-29","18","-21","35","-18","32","-8","33","-4","69","rrcurveto","252","hlineto","-6","84","-15","47","-32","38","-33","39","-46","20","-55","0","rrcurveto","-125","-84","-99","-146","-146","82","-96","124","hvcurveto","81","0","49","32","65","93","rrcurveto","-262","171","rmoveto","3","120","18","40","49","0","28","0","19","-16","8","-31","5","-19","2","-28","2","-51","rrcurveto","-15","vlineto","endchar"], +f: ["-282","0","24","393","44","199","31","hstem","71","139","vstem","71","417","rmoveto","-333","vlineto","0","-43","-11","-12","-46","-5","rrcurveto","-24","278","24","vlineto","-70","2","-12","12","0","65","rrcurveto","314","87","44","-87","122","vlineto","55","15","22","35","18","11","-7","-12","vhcurveto","0","-4","-3","-7","-6","-10","-9","-15","-4","-11","0","-10","rrcurveto","-31","26","-24","34","37","25","25","37","59","-59","41","-84","vhcurveto","-67","0","-52","-24","-27","-44","-22","-35","-7","-41","0","-86","rrcurveto","-57","-44","hlineto","endchar"], +g: ["-206","32","122","120","87","27","216","53","-9","31","hstemhm","28","88","-79","137","132","135","-37","79","hintmask","-reserved-","482","398","rmoveto","53","-130","vlineto","hintmask","-reserved-","-44","16","-28","6","-40","0","-119","0","-84","-66","0","-95","0","-34","13","-33","23","-28","22","-24","19","-13","47","-20","-79","-27","-40","-38","0","-52","0","-41","18","-18","64","-23","rrcurveto","hintmask","-11","-63","-9","-33","-25","0","-41","rrcurveto","-58","75","-34","126","166","88","52","99","77","-62","46","-102","vhcurveto","-65","hlineto","-80","-20","7","28","30","28","22","40","hvcurveto","45","-1","rlineto","47","0","25","6","34","20","rrcurveto","hintmask","-reserved-","45","26","23","41","0","53","0","40","-12","30","-28","28","rrcurveto","-77","-450","rmoveto","hintmask","-11","54","26","-17","-33","-46","-55","-26","-99","-88","-46","23","44","hvcurveto","0","21","7","11","28","23","rrcurveto","hintmask","-reserved-","89","494","rmoveto","47","19","-38","-93","-93","-19","-36","-47","-48","-18","36","93","hvcurveto","94","19","37","47","vhcurveto","endchar"], +h: ["-59","0","24","382","67","179","24","hstem","69","139","138","139","vstem","208","676","rmoveto","-192","-24","hlineto","46","-9","7","-8","0","-41","rrcurveto","-510","vlineto","0","-42","-8","-9","-45","-9","rrcurveto","-24","241","24","vlineto","-37","5","-12","15","0","37","rrcurveto","267","vlineto","0","4","7","10","10","9","22","23","24","12","23","0","rrcurveto","35","17","-27","-56","hvcurveto","-242","vlineto","0","-37","-13","-16","-34","-4","rrcurveto","-24","235","24","vlineto","-36","3","-13","15","0","42","rrcurveto","248","vlineto","86","-53","55","-82","vhcurveto","-53","0","-37","-20","-52","-58","rrcurveto","endchar"], +i: ["-337","0","24","413","24","75","155","hstemhm","60","155","-146","139","hintmask","208","461","rmoveto","-192","-24","hlineto","44","-9","9","-9","0","-41","rrcurveto","-294","vlineto","0","-41","-7","-8","-46","-11","rrcurveto","-24","239","24","vlineto","-35","5","-12","14","0","38","rrcurveto","hintmask","-70","610","rmoveto","-43","-35","-35","-42","-45","33","-33","44","44","34","33","44","hvcurveto","43","-34","35","-43","vhcurveto","endchar"], +j: ["-282","-203","31","609","24","75","155","hstemhm","108","155","-142","139","hintmask","260","461","rmoveto","-202","-24","hlineto","51","-4","12","-12","0","-43","rrcurveto","-474","vlineto","-53","-15","-23","-33","-19","-13","7","10","vhcurveto","0","5","3","7","6","10","10","16","4","11","0","10","rrcurveto","30","-27","24","-32","-37","-25","-25","-36","-59","58","-41","82","vhcurveto","69","0","53","27","28","49","19","32","8","38","0","59","rrcurveto","hintmask","-75","689","rmoveto","-43","-34","-35","-42","-45","32","-33","45","43","35","34","43","hvcurveto","43","-35","35","-43","vhcurveto","endchar"], +k: ["-59","0","24","628","24","hstem","70","139","vstem","513","461","rmoveto","-214","-23","hlineto","11","-2","10","-1","3","-1","24","-3","11","-7","0","-13","0","-9","-10","-18","-11","-11","rrcurveto","-128","-128","0","431","-187","0","0","-24","rlineto","34","-3","14","-17","0","-38","rrcurveto","-510","vlineto","0","-39","-15","-18","-33","-3","rrcurveto","-24","239","24","vlineto","-47","7","-5","6","0","47","rrcurveto","0","114","23","24","95","-134","rlineto","17","-25","7","-12","0","-8","0","-12","-14","-6","-28","-1","rrcurveto","-24","234","24","vlineto","-11","0","-5","3","-9","12","rrcurveto","-194","268","rlineto","100","105","26","18","63","8","rrcurveto","endchar"], +l: ["-337","0","24","628","24","hstem","67","139","vstem","206","676","rmoveto","-190","-24","hlineto","35","-3","16","-18","0","-37","rrcurveto","-510","vlineto","0","-37","-17","-20","-34","-3","rrcurveto","-24","239","24","vlineto","-33","1","-16","19","0","40","rrcurveto","endchar"], +m: ["218","0","24","382","67","-36","24","hstemhm","71","139","138","139","138","139","hintmask","207","461","rmoveto","-191","-24","hlineto","44","-6","11","-12","0","-41","rrcurveto","-294","vlineto","0","-41","-11","-11","-44","-8","rrcurveto","-24","240","24","vlineto","-35","5","-11","14","0","38","rrcurveto","267","vlineto","0","6","16","19","13","10","rrcurveto","hintmask","21","16","17","7","17","0","rrcurveto","39","15","-23","-60","hvcurveto","-242","vlineto","0","-41","-11","-13","-37","-3","rrcurveto","-24","234","24","vlineto","-35","4","-12","15","0","38","rrcurveto","267","vlineto","0","5","16","19","13","10","22","17","17","7","17","0","rrcurveto","38","15","-24","-59","hvcurveto","-242","vlineto","0","-42","-11","-12","-38","-3","rrcurveto","-24","238","24","vlineto","-39","2","-11","12","0","43","rrcurveto","251","vlineto","86","-53","55","-82","vhcurveto","-57","0","-38","-23","-52","-64","-30","63","-35","24","-63","0","-63","0","-46","-27","-38","-60","rrcurveto","endchar"], +n: ["-59","0","24","382","67","-36","24","hstemhm","74","139","138","139","hintmask","212","461","rmoveto","-191","-24","hlineto","44","-7","9","-10","0","-42","rrcurveto","-294","vlineto","0","-42","-8","-9","-45","-9","rrcurveto","-24","241","24","vlineto","-37","5","-12","15","0","37","rrcurveto","267","vlineto","0","4","7","10","10","9","rrcurveto","hintmask","22","23","24","12","23","0","rrcurveto","35","17","-27","-56","hvcurveto","-242","vlineto","0","-37","-13","-16","-34","-4","rrcurveto","-24","235","24","vlineto","-39","3","-10","12","0","42","rrcurveto","251","vlineto","86","-53","55","-82","vhcurveto","-60","0","-46","-28","-37","-59","rrcurveto","endchar"], +o: ["-14","31","425","31","hstem","25","147","157","147","vstem","251","473","rmoveto","-127","-99","-105","-136","-143","95","-103","131","129","96","104","139","140","-96","104","-129","hvcurveto","1","-31","rmoveto","58","19","-55","-164","-154","-20","-52","-58","-59","-20","51","146","176","18","52","62","hvcurveto","endchar"], +p: ["-59","-205","21","-21","24","-24","205","-13","55","374","57","-36","24","hstemhm","75","139","162","148","hintmask","212","461","rmoveto","-191","-24","hlineto","44","-7","10","-10","0","-42","rrcurveto","-501","vlineto","0","-41","-8","-9","-48","-8","rrcurveto","hintmask","-24","273","vlineto","hintmask","21","vlineto","-61","3","-17","20","0","67","rrcurveto","141","vlineto","48","-47","26","-13","44","0","rrcurveto","112","80","104","148","139","-75","95","-111","hvcurveto","-59","0","-36","-23","-31","-58","rrcurveto","hintmask","2","-46","rmoveto","0","7","9","16","12","13","20","22","23","12","22","0","rrcurveto","52","24","-60","-131","-124","-28","-59","-57","hvcurveto","-33","0","-29","23","-15","38","rrcurveto","endchar"], +r: ["-171","0","24","413","24","-8","20","hstemhm","83","139","hintmask","218","461","rmoveto","-189","-24","hlineto","43","-6","11","-13","0","-40","rrcurveto","-294","vlineto","0","-41","-10","-11","-44","-8","rrcurveto","-24","266","24","vlineto","-61","4","-12","13","0","62","rrcurveto","189","vlineto","52","28","43","33","vhcurveto","8","0","9","-7","11","-16","19","-27","15","-9","26","0","rrcurveto","37","26","28","39","hvcurveto","hintmask","45","-34","33","-47","vhcurveto","-50","0","-38","-27","-47","-67","rrcurveto","endchar"], +s: ["-226","-14","34","420","33","hstem","27","100","138","96","vstem","340","326","rmoveto","145","-22","vlineto","-6","-15","-6","-5","-12","0","-6","0","-10","2","-16","5","-33","11","-23","4","-22","0","-91","0","-66","-62","0","-84","0","-66","41","-46","101","-43","68","-30","28","-25","0","-32","rrcurveto","-39","-30","-26","-45","vhcurveto","-70","0","-46","45","-21","87","rrcurveto","-28","-165","25","hlineto","11","21","6","7","9","0","5","0","8","-2","10","-4","27","-12","53","-11","28","0","91","0","63","62","0","90","0","71","-39","43","-99","42","-68","29","-28","25","0","34","rrcurveto","33","28","25","38","vhcurveto","26","0","27","-11","22","-21","21","-20","11","-18","15","-44","rrcurveto","endchar"], +t: ["-282","-12","71","358","44","hstem","72","139","vstem","305","461","rmoveto","-94","169","-25","hlineto","-61","-86","-40","-45","-65","-55","rrcurveto","-27","52","-324","vlineto","-65","43","-40","69","vhcurveto","67","0","40","30","41","82","rrcurveto","-25","11","rlineto","-20","-38","-16","-14","-21","0","rrcurveto","-28","-11","17","40","hvcurveto","301","94","vlineto","endchar"], +u: ["-59","-14","65","-31","23","394","24","hstemhm","65","139","138","139","hintmask","343","-13","rmoveto","43","15","24","4","65","7","rrcurveto","62","7","0","23","rlineto","-44","2","-12","13","0","43","rrcurveto","360","-201","-24","vlineto","50","-4","12","-12","0","-43","rrcurveto","-283","vlineto","hintmask","-33","-33","-21","-11","-28","0","rrcurveto","-41","-15","20","51","hvcurveto","339","-188","-24","vlineto","41","-8","8","-9","0","-42","rrcurveto","-252","vlineto","-88","50","-52","83","vhcurveto","52","0","35","16","58","50","rrcurveto","endchar"], +v: ["-14","20","435","20","hstem","485","461","rmoveto","-151","-24","hlineto","43","-2","12","-7","0","-24","0","-11","-4","-16","-7","-18","rrcurveto","-72","-182","-79","203","rlineto","-7","19","-2","6","0","6","0","15","10","7","25","2","2","0","8","1","8","1","rrcurveto","24","-250","-24","vlineto","23","-3","6","-3","6","-9","2","1","47","-100","16","-41","rrcurveto","120","-296","26","0","160","396","rlineto","19","44","8","8","31","3","rrcurveto","endchar"], +w: ["107","-14","20","435","20","hstem","707","461","rmoveto","-135","-24","hlineto","37","-4","11","-8","0","-23","0","-12","-13","-37","-31","-79","-15","-39","-8","-21","-12","-34","-10","41","-3","12","-21","74","-20","69","-7","28","0","9","0","16","10","5","38","3","rrcurveto","24","-234","-24","vlineto","39","-4","1","-1","19","-66","rrcurveto","6","-19","-68","-171","-24","64","rlineto","-9","21","-7","19","-5","14","-28","70","-11","32","0","13","0","16","10","8","28","4","rrcurveto","24","-222","-24","vlineto","26","-5","4","-6","27","-66","rrcurveto","148","-374","24","0","125","310","102","-310","23","0","155","401","rlineto","16","37","8","8","26","5","rrcurveto","endchar"], +x: ["0","20","421","20","hstem","484","24","rmoveto","-16","5","-7","4","-7","11","rrcurveto","-148","228","101","126","rlineto","19","23","20","11","31","5","rrcurveto","24","-168","-24","vlineto","9","-1","8","-1","3","0","23","-1","8","-6","0","-15","0","-15","-10","-17","-28","-32","-6","-6","-15","-19","-15","-21","-6","7","-4","6","-3","4","-32","42","-26","43","0","13","rrcurveto","0","12","14","6","33","1","rrcurveto","24","-250","-24","vlineto","26","-4","6","-5","20","-30","rrcurveto","128","-197","rlineto","-29","-37","-27","-33","-9","-14","-56","-74","-20","-17","-37","-2","rrcurveto","-24","169","24","vlineto","-36","2","-14","7","0","15","0","15","26","42","38","46","2","3","7","8","7","9","rrcurveto","42","-63","rlineto","23","-33","10","-19","0","-12","0","-12","-14","-6","-31","-2","rrcurveto","-24","241","vlineto","endchar"], +y: ["-205","57","589","20","hstem","16","119","vstem","480","461","rmoveto","-151","-24","hlineto","43","-2","12","-7","0","-24","0","-11","-2","-9","-9","-25","rrcurveto","-68","-192","-72","185","rlineto","-20","51","0","0","0","8","0","14","12","9","25","2","rrcurveto","16","1","0","24","-250","0","0","-24","rlineto","23","-3","6","-3","6","-9","3","0","45","-98","17","-42","rrcurveto","120","-295","-18","-53","rlineto","-17","-50","-26","-32","-23","0","-9","0","-8","8","0","9","0","1","0","2","1","3","1","5","1","5","0","4","rrcurveto","29","-24","20","-34","-37","-27","-26","-38","-46","40","-33","57","vhcurveto","34","0","29","12","21","21","21","23","20","40","35","94","rrcurveto","149","397","rlineto","17","42","10","10","31","3","rrcurveto","endchar"], +z: ["-171","0","32","409","20","hstem","420","160","rmoveto","-28","hlineto","-9","-32","-8","-18","-16","-21","-32","-44","-33","-13","-80","0","rrcurveto","-29","0","231","403","0","26","-371","0","-7","-142","26","0","rlineto","25","95","26","16","140","-1","rrcurveto","-234","-404","0","-25","383","0","rlineto","endchar"] +}; diff --git a/test.html b/test.html index 83d48741e..b70351f2f 100644 --- a/test.html +++ b/test.html @@ -7,6 +7,7 @@ + From da69361ae057158ab6d233c2ee0a2437011374a4 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 08:40:28 +0200 Subject: [PATCH 18/77] Add the beginning of a working CFF font encoder --- PDFFont.js | 78 +++++++++++++++++++++++++++++++++++++++---------- PDFFontUtils.js | 6 ++-- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index c001c825e..e3ddd213d 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -202,7 +202,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { "21": "rmoveto", "22": "hmoveto", "30": "vhcurveto", - "31": "hcurveto" + "31": "hvcurveto" }; function decodeCharString(aStream) { @@ -914,7 +914,7 @@ Type1Font.prototype = { //Top Dict Index var topDictIndex = [ - 0x00, 0x01, 0x01, 0x01, 0x29, + 0x00, 0x01, 0x01, 0x01, 0x2A, 248, 27, 0, // version 248, 28, 1, // Notice 248, 29, 2, // FullName @@ -922,9 +922,9 @@ Type1Font.prototype = { 248, 20, 4, // Weigth 82, 251, 98, 250, 105, 249, 72, 5, // FontBBox 248, 136, 15, // charset (offset: 500) - 28, 0, 0, 16, // Encoding (offset: 600) - 248, 236, 17, // CharStrings - 28, 0, 55, 28, 15, 160, 18 // Private (offset: 4000) + 28, 0, 0, 16, // Encoding + 28, 7, 208, 17, // CharStrings (offset: 2000) + 28, 0, 55, 28, 39, 16, 18 // Private (offset: 10000) ]; cff.set(topDictIndex, currentOffset); currentOffset += topDictIndex.length; @@ -956,32 +956,74 @@ Type1Font.prototype = { cff.set(empty, currentOffset); currentOffset += empty.length; - //Declare the letter 'C' + //Declare the letters var charset = [ - 0x00, 0x00, 0x42 + 0x00 ]; + var limit = 30; + for (var glyph in charstrings.map) { + if (!limit--) + break; + var index = CFFStrings.indexOf(glyph); + var bytes = integerToBytes(index, 2); + charset.push(bytes[0]); + charset.push(bytes[1]); + } cff.set(charset, currentOffset); currentOffset += charset.length; // Fill the space between this and the charstrings data by '1' - var empty = new Array(600 - currentOffset); + var empty = new Array(2000 - currentOffset); for (var i = 0; i < empty.length; i++) empty[i] = 0x01; cff.set(empty, currentOffset); currentOffset += empty.length; + var getNumFor = { + "hstem": 1, + "vstem": 3, + "vmoveto": 4, + "rlineto": 5, + "hlineto": 6, + "vlineto": 7, + "rrcurveto": 8, + "endchar": 14, + "rmoveto": 21, + "vhcurveto": 30, + "hvcurveto": 31, + }; + // Encode the glyph and add it to the FUX - var charStringsIndex = [ - 0x00, 0x02, 0x01, 0x01, 0x03, 0x05, - 0x40, 0x0E, - 0xAF, 0x0E - ]; - cff.set(charStringsIndex, currentOffset); + var r = [[0x40, 0xEA]]; + var limit = 30; + for (var glyph in glyphs) { + if (!limit--) + break; + var data = glyphs[glyph].slice(); + var charstring = []; + for (var i = 0; i < data.length; i++) { + var c = data[i]; + if (!IsNum(c)) { + var token = getNumFor[c]; + if (!token) + error(c); + charstring.push(token); + } else { + var bytes = encodeNumber(c); + for (var j = 0; j < bytes.length; j++) + charstring.push(bytes[j]); + } + } + r.push(charstring); + } + + var charStringsIndex = this.createCFFIndexHeader(r, true); + cff.set(charStringsIndex.join(" ").split(" "), currentOffset); currentOffset += charStringsIndex.length; // Fill the space between this and the private dict data by '1' - var empty = new Array(4000 - currentOffset); + var empty = new Array(10000 - currentOffset); for (var i = 0; i < empty.length; i++) empty[i] = 0x01; cff.set(empty, currentOffset); @@ -1018,6 +1060,7 @@ Type1Font.prototype = { var file = new Uint8Array(cff, 0, currentOffset); var parser = new Type2Parser(); + log("parse"); parser.parse(new Stream(file)); var file64 = Base64Encoder.encode(file); @@ -1064,6 +1107,8 @@ Type1Font.prototype = { function integerToBytes(aValue, aBytesCount) { var bytes = []; + for (var i = 0; i < aBytesCount; i++) + bytes[i] = 0x00; do { bytes[--aBytesCount] = (aValue & 0xFF); @@ -1106,4 +1151,5 @@ function encodeNumber(aValue) { } else { error("Value: " + aValue + " is not allowed"); } -} +}; + diff --git a/PDFFontUtils.js b/PDFFontUtils.js index 02c588217..16d1150ab 100644 --- a/PDFFontUtils.js +++ b/PDFFontUtils.js @@ -22,9 +22,8 @@ function readCharset(aStream, aCharstrings) { var count = aCharstrings.length - 1; for (var i = 1; i < count + 1; i++) { var sid = aStream.getByte() << 8 | aStream.getByte(); - log(sid); charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]); - log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]); + //log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]); } } else if (format == 1) { error("Charset Range are not supported"); @@ -218,7 +217,7 @@ var Type2Parser = function(aFilePath) { var font = new Dict(); // Turn on this flag for additional debugging logs - var debug = true; + var debug = false; function dump(aStr) { if (debug) @@ -227,7 +226,6 @@ var Type2Parser = function(aFilePath) { function parseAsToken(aString, aMap) { var decoded = readFontDictData(aString, aMap); - log(decoded); var stack = []; var count = decoded.length; From 4191485e1f4fcc1c5b6df6c3469df1933c19e95d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 18:38:57 +0200 Subject: [PATCH 19/77] Add a debug writeToFile function and remove aggregations for Type2 fonts --- PDFFont.js | 55 ++++++++++++++----------------------------------- PDFFontUtils.js | 23 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index e3ddd213d..b81b2b2f4 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -729,24 +729,18 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { error(obj + " parsing is not implemented (yet)"); break; - case "vstem3": - operandStack.push("vstem"); - break; - - case "vstem": - //log(obj + " is not converted (yet?)"); - operandStack.push("vstem"); - break; - case "closepath": case "return": break; - case "hlineto": - case "vlineto": - case "rlineto": - case "rrcurveto": - aggregateCommand(obj); + case "vstem3": + case "vstem": + operandStack.push("vstem"); + break; + + case "hstem": + case "hstem3": + operandStack.push("hstem"); break; case "rmoveto": @@ -763,20 +757,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { operandStack.push("rmoveto"); break; - case "hstem": - case "hstem3": - var dy = operandStack.pop(); - var y = operandStack.pop(); - if (operandStack.peek() == "hstem" || - operandStack.peek() == "hstem3") - operandStack.pop(); - - operandStack.push(y - lastPoint); - lastPoint = y + dy; - - operandStack.push(dy); - operandStack.push("hstem"); - break; case "callsubr": var index = operandStack.pop(); @@ -960,10 +940,7 @@ Type1Font.prototype = { var charset = [ 0x00 ]; - var limit = 30; for (var glyph in charstrings.map) { - if (!limit--) - break; var index = CFFStrings.indexOf(glyph); var bytes = integerToBytes(index, 2); charset.push(bytes[0]); @@ -990,16 +967,14 @@ Type1Font.prototype = { "rrcurveto": 8, "endchar": 14, "rmoveto": 21, + "hmoveto": 22, "vhcurveto": 30, "hvcurveto": 31, }; // Encode the glyph and add it to the FUX var r = [[0x40, 0xEA]]; - var limit = 30; for (var glyph in glyphs) { - if (!limit--) - break; var data = glyphs[glyph].slice(); var charstring = []; for (var i = 0; i < data.length; i++) { @@ -1060,16 +1035,18 @@ Type1Font.prototype = { var file = new Uint8Array(cff, 0, currentOffset); var parser = new Type2Parser(); - log("parse"); - parser.parse(new Stream(file)); - var file64 = Base64Encoder.encode(file); - console.log(file64); + + log("==================== debug ===================="); + log("== parse"); + parser.parse(new Stream(file)); var data = []; for (var i = 0; i < currentOffset; i++) data.push(cff[i]); - log(data); + + log("== write to file"); + writeToFile(data, "/tmp/pdf.js.cff"); }, createCFFIndexHeader: function(aObjects, aIsByte) { diff --git a/PDFFontUtils.js b/PDFFontUtils.js index 16d1150ab..e3b6a5a07 100644 --- a/PDFFontUtils.js +++ b/PDFFontUtils.js @@ -349,3 +349,26 @@ var cffData = xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response; var cff = new Type2Parser("titi.cff"); //cff.parse(new Stream(cffData)); + + +/** + * Write to a file (works only on Firefox in privilege mode"); + */ + 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(); + }; + From ffa52f9dbd157802f583698cc8db1d48e09f2662 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 18:46:26 +0200 Subject: [PATCH 20/77] Remove the aggregate commands and do some methods dance --- PDFFont.js | 263 +++++++++++++++++------------------------------------ 1 file changed, 85 insertions(+), 178 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index b81b2b2f4..d24681c77 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -604,94 +604,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { return false; } - function aggregateCommand(aCommand) { - var command = aCommand; - switch (command) { - case "hstem": - case "vstem": - break; - - case "rrcurveto": - var stack = [operandStack.pop(), operandStack.pop(), - operandStack.pop(), operandStack.pop(), - operandStack.pop(), operandStack.pop()]; - var next = true; - while (next) { - var op = operandStack.peek(); - if (op == "rrcurveto") { - operandStack.pop(); - stack.push(operandStack.pop()); - stack.push(operandStack.pop()); - stack.push(operandStack.pop()); - stack.push(operandStack.pop()); - stack.push(operandStack.pop()); - stack.push(operandStack.pop()); - } else { - next = false; - } - } - break; - - case "hlineto": - case "vlineto": - var last = command; - var stack = [operandStack.pop()]; - var next = true; - while (next) { - var op = operandStack.peek(); - if (op == "vlineto" && last == "hlineto") { - operandStack.pop(); - stack.push(operandStack.pop()); - } else if (op == "hlineto" && last == "vlineto") { - operandStack.pop(); - stack.push(operandStack.pop()); - } else if (op == "rlineto" && command == "hlineto") { - operandStack.pop(); - var x = stack.pop(); - operandStack.push(0); - operandStack.push(x); - command = "rlineto"; - } else if (op == "rlineto" && command == "vlineto") { - operandStack.pop(); - operandStack.push(0); - command = "rlineto"; - } else { - next = false; - } - last = op; - } - break; - - case "rlineto": - var stack = [operandStack.pop(), operandStack.pop()]; - var next = true; - while (next) { - var op = operandStack.peek(); - if (op == "rlineto") { - operandStack.pop(); - stack.push(operandStack.pop()); - stack.push(operandStack.pop()); - } else if (op == "hlineto") { - operandStack.pop(); - stack.push(0); - stack.push(operandStack.pop()); - } else if (op == "vlineto") { - operandStack.pop(); - stack.push(operandStack.pop()); - stack.push(0); - } else { - next= false; - } - } - break; - } - - while (stack.length) - operandStack.push(stack.pop()); - operandStack.push(command); - }; - - /* * Flatten the commands by interpreting the postscript code and replacing * every 'callsubr', 'callothersubr' by the real commands. @@ -852,6 +764,87 @@ Type1Font.prototype = { }; }, + + createCFFIndexHeader: function(aObjects, aIsByte) { + var data = []; + + // First 2 bytes contains the number of objects contained into this index + var count = aObjects.length; + var bytes = this.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 = this.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][j].charCodeAt(0)); + } + return data; + }, + + integerToBytes: function(aValue, aBytesCount) { + var bytes = []; + for (var i = 0; i < aBytesCount; i++) + bytes[i] = 0x00; + + do { + bytes[--aBytesCount] = (aValue & 0xFF); + aValue = aValue >> 8; + } while (aBytesCount && aValue > 0); + + return bytes; + }, + + encodeNumber: function(aValue) { + var x = 0; + if (aValue >= -107 && aValue <= 107) { + return [aValue + 139]; + } else if (aValue >= 108 && aValue <= 1131) { + x = aValue - 108; + return [ + this.integerToBytes(x / 256 + 247, 1), + x % 256 + ]; + } else if (aValue >= -1131 && aValue <= -108) { + x = Math.abs(aValue) - 108; + return [ + this.integerToBytes(x / 256 + 251, 1), + x % 256 + ]; + } else if (aValue >= -32768 && aValue <= 32767) { + return [ + 28, + integerToBytes(aValue >> 8, 1), + integerToBytes(aValue, 1) + ]; + } else if (aValue >= (-2147483647-1) && aValue <= 2147483647) { + return [ + 0xFF, + integerToBytes(aValue >> 24, 1), + integerToBytes(aValue >> 16, 1), + integerToBytes(aValue >> 8, 1), + integerToBytes(aValue, 1) + ]; + } else { + error("Value: " + aValue + " is not allowed"); + } + }, + convertToOTF: function(aFontName) { var font = Fonts.get(aFontName); @@ -871,11 +864,6 @@ Type1Font.prototype = { for (var glyph in charstrings.map) { var charstring = charstrings.get(glyph); glyphs[glyph] = parser.flattenCharstring(charstring, defaultWidth, nominalWidth, subrs); - - //log("=================================== " + glyph + " =============================="); - //log(charstrings.get(glyph)); - //log(flattenedCharstring); - //log(validationData[glyph]); } // Create a CFF font data @@ -942,7 +930,7 @@ Type1Font.prototype = { ]; for (var glyph in charstrings.map) { var index = CFFStrings.indexOf(glyph); - var bytes = integerToBytes(index, 2); + var bytes = this.integerToBytes(index, 2); charset.push(bytes[0]); charset.push(bytes[1]); } @@ -985,7 +973,7 @@ Type1Font.prototype = { error(c); charstring.push(token); } else { - var bytes = encodeNumber(c); + var bytes = this.encodeNumber(c); for (var j = 0; j < bytes.length; j++) charstring.push(bytes[j]); } @@ -1033,12 +1021,11 @@ Type1Font.prototype = { cff.set(shit, currentOffset); currentOffset += shit.length; - var file = new Uint8Array(cff, 0, currentOffset); - var parser = new Type2Parser(); - log("==================== debug ===================="); log("== parse"); + var file = new Uint8Array(cff, 0, currentOffset); + var parser = new Type2Parser(); parser.parse(new Stream(file)); var data = []; @@ -1047,86 +1034,6 @@ Type1Font.prototype = { log("== write to file"); writeToFile(data, "/tmp/pdf.js.cff"); - }, - - createCFFIndexHeader: function(aObjects, aIsByte) { - var data = []; - - // First 2 bytes contains the number of objects contained into this index - var count = aObjects.length; - var bytes = 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 = 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][j].charCodeAt(0)); - } - return data; - } -}; - -function integerToBytes(aValue, aBytesCount) { - var bytes = []; - for (var i = 0; i < aBytesCount; i++) - bytes[i] = 0x00; - - do { - bytes[--aBytesCount] = (aValue & 0xFF); - aValue = aValue >> 8; - } while (aBytesCount && aValue > 0); - - return bytes; -}; - -function encodeNumber(aValue) { - var x = 0; - if (aValue >= -107 && aValue <= 107) { - return [aValue + 139]; - } else if (aValue >= 108 && aValue <= 1131) { - x = aValue - 108; - return [ - integerToBytes(x / 256 + 247, 1), - x % 256 - ]; - } else if (aValue >= -1131 && aValue <= -108) { - x = Math.abs(aValue) - 108; - return [ - integerToBytes(x / 256 + 251, 1), - x % 256 - ]; - } else if (aValue >= -32768 && aValue <= 32767) { - return [ - 28, - integerToBytes(aValue >> 8, 1), - integerToBytes(aValue, 1) - ]; - } else if (aValue >= (-2147483647-1) && aValue <= 2147483647) { - return [ - 0xFF, - integerToBytes(aValue >> 24, 1), - integerToBytes(aValue >> 16, 1), - integerToBytes(aValue >> 8, 1), - integerToBytes(aValue, 1) - ]; - } else { - error("Value: " + aValue + " is not allowed"); } }; From d1d66211644eee43292a874ec076b6bfb0169a6a Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 19:27:34 +0200 Subject: [PATCH 21/77] Remove some useless bits of code --- PDFFont.js | 90 +++++++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index d24681c77..1344b0456 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -611,7 +611,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * as descrived in 'Using Subroutines' of 'Adobe Type 1 Font Format', * chapter 8. */ - this.flattenCharstring = function(aCharstring, aDefaultWidth, aNominalWidth, aSubrs) { + this.flattenCharstring = function(aCharstring, aDefaultWidth, aSubrs) { operandStack.clear(); executionStack.clear(); executionStack.push(aCharstring); @@ -631,7 +631,21 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { leftSidebearing = operandStack.pop(); if (charWidthVector != aDefaultWidth) - operandStack.push(charWidthVector - aNominalWidth); + operandStack.push(charWidthVector - aDefaultWidth); + break; + + case "rmoveto": + var dy = operandStack.pop(); + var dx = operandStack.pop(); + + if (leftSidebearing) { + dx += leftSidebearing; + leftSidebearing = 0; + } + + operandStack.push(dx); + operandStack.push(dy); + operandStack.push("rmoveto"); break; case "setcurrentpoint": @@ -655,21 +669,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { operandStack.push("hstem"); break; - case "rmoveto": - var dy = operandStack.pop(); - var dx = operandStack.pop(); - - if (leftSidebearing) { - dx += leftSidebearing; - leftSidebearing = 0; - } - - operandStack.push(dx); - operandStack.push(dy); - operandStack.push("rmoveto"); - break; - - case "callsubr": var index = operandStack.pop(); executionStack.push(aSubrs[index].slice()); @@ -723,14 +722,16 @@ var Type1Font = function(aFontName, aFontFile) { this.parser = new Type1Parser(ASCIIStream, binaryStream); var fontName = this.parser.parse(); - this.convertToOTF(fontName); + var font = Fonts.get(fontName); + this.convertToOTF(this.convertToCFF(font), font); + var end = Date.now(); log("Time to parse font is:" + (end - start)); } }; Type1Font.prototype = { - getDefaultWidths: function(aCharstrings) { + getDefaultWidth: function(aCharstrings) { var defaultWidth = 0; var defaultUsedCount = 0; @@ -746,25 +747,9 @@ Type1Font.prototype = { widths[width] = usedCount; } - defaultWidth = parseInt(defaultWidth); - - var maxNegDistance = 0, maxPosDistance = 0; - for (var width in widths) { - var diff = width - defaultWidth; - if (diff < 0 && diff < maxNegDistance) { - maxNegDistance = diff; - } else if (diff > 0 && diff > maxPosDistance) { - maxPosDistance = diff; - } - } - - return { - default: defaultWidth, - nominal: defaultWidth + (maxPosDistance + maxNegDistance) / 2 - }; + return parseInt(defaultWidth); }, - createCFFIndexHeader: function(aObjects, aIsByte) { var data = []; @@ -845,27 +830,27 @@ Type1Font.prototype = { } }, - convertToOTF: function(aFontName) { - var font = Fonts.get(aFontName); - - var charstrings = font.get("CharStrings") - var defaultWidths = this.getDefaultWidths(charstrings); - var defaultWidth = defaultWidths.default; - var nominalWidth = defaultWidths.nominal; + convertToCFF: function(aFont) { + var charstrings = aFont.get("CharStrings") + var defaultWidth = this.getDefaultWidth(charstrings); log("defaultWidth to used: " + defaultWidth); - log("nominalWidth to used: " + nominalWidth); - log("Hack nonimal:" + (nominalWidth = 615)); + var charstringsCount = 0; + var charstringsDataLength = 0; var glyphs = {}; - var subrs = font.get("Private").get("Subrs"); + var subrs = aFont.get("Private").get("Subrs"); var parser = new Type1Parser(); for (var glyph in charstrings.map) { var charstring = charstrings.get(glyph); - glyphs[glyph] = parser.flattenCharstring(charstring, defaultWidth, nominalWidth, subrs); + glyphs[glyph] = parser.flattenCharstring(charstring, defaultWidth, subrs); + charstringsCount++; + charstringsDataLength += glyphs[glyph].length; } + log("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")"); + // Create a CFF font data var cff = new Uint8Array(20000); var currentOffset = 0; @@ -876,7 +861,7 @@ Type1Font.prototype = { cff.set(header); // Names Index - var nameIndex = this.createCFFIndexHeader([aFontName]); + var nameIndex = this.createCFFIndexHeader([aFont.get("FontName")]); cff.set(nameIndex, currentOffset); currentOffset += nameIndex.length; @@ -995,7 +980,7 @@ Type1Font.prototype = { // Private Data var privateData = [ 248, 136, 20, - 248, 251, 21, + 248, 136, 21, 119, 159, 248, 97, 159, 247, 87, 159, 6, 30, 10, 3, 150, 37, 255, 12, 9, 139, 12, 10, @@ -1023,10 +1008,12 @@ Type1Font.prototype = { log("==================== debug ===================="); + /* log("== parse"); var file = new Uint8Array(cff, 0, currentOffset); var parser = new Type2Parser(); parser.parse(new Stream(file)); + */ var data = []; for (var i = 0; i < currentOffset; i++) @@ -1034,6 +1021,11 @@ Type1Font.prototype = { log("== write to file"); writeToFile(data, "/tmp/pdf.js.cff"); + + return data; + }, + + convertToOTF: function(aData, aFont) { } }; From a73ffc2d30ba513dcd1f02452f368f982db89edc Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 10 Jun 2011 20:45:42 +0200 Subject: [PATCH 22/77] Do not add empty spaces anymore --- PDFFont.js | 180 +++++++++++++++++++++++------------------------- PDFFontUtils.js | 5 +- 2 files changed, 91 insertions(+), 94 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 1344b0456..b616075e4 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -755,6 +755,9 @@ Type1Font.prototype = { // 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 = this.integerToBytes(count, 2); for (var i = 0; i < bytes.length; i++) data.push(bytes[i]); @@ -777,7 +780,7 @@ Type1Font.prototype = { for (var i =0; i < count; i++) { for (var j = 0; j < aObjects[i].length; j++) - data.push(aIsByte ? aObjects[i][j] : aObjects[i][j].charCodeAt(0)); + data.push(aIsByte ? aObjects[i][j] : aObjects[i].charCodeAt(j)); } return data; }, @@ -797,33 +800,20 @@ Type1Font.prototype = { encodeNumber: function(aValue) { var x = 0; - if (aValue >= -107 && aValue <= 107) { - return [aValue + 139]; - } else if (aValue >= 108 && aValue <= 1131) { - x = aValue - 108; - return [ - this.integerToBytes(x / 256 + 247, 1), - x % 256 - ]; - } else if (aValue >= -1131 && aValue <= -108) { - x = Math.abs(aValue) - 108; - return [ - this.integerToBytes(x / 256 + 251, 1), - x % 256 - ]; - } else if (aValue >= -32768 && aValue <= 32767) { + // XXX we don't really care about Type2 optimization here... + if (aValue >= -32768 && aValue <= 32767) { return [ 28, - integerToBytes(aValue >> 8, 1), - integerToBytes(aValue, 1) + this.integerToBytes(aValue >> 8, 1), + this.integerToBytes(aValue, 1) ]; } else if (aValue >= (-2147483647-1) && aValue <= 2147483647) { return [ 0xFF, - integerToBytes(aValue >> 24, 1), - integerToBytes(aValue >> 16, 1), - integerToBytes(aValue >> 8, 1), - integerToBytes(aValue, 1) + this.integerToBytes(aValue >> 24, 1), + this.integerToBytes(aValue >> 16, 1), + this.integerToBytes(aValue >> 8, 1), + this.integerToBytes(aValue, 1) ]; } else { error("Value: " + aValue + " is not allowed"); @@ -834,11 +824,8 @@ Type1Font.prototype = { var charstrings = aFont.get("CharStrings") var defaultWidth = this.getDefaultWidth(charstrings); - log("defaultWidth to used: " + defaultWidth); - var charstringsCount = 0; var charstringsDataLength = 0; - var glyphs = {}; var subrs = aFont.get("Private").get("Subrs"); var parser = new Type1Parser(); @@ -848,7 +835,6 @@ Type1Font.prototype = { charstringsCount++; charstringsDataLength += glyphs[glyph].length; } - log("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")"); // Create a CFF font data @@ -865,71 +851,33 @@ Type1Font.prototype = { cff.set(nameIndex, currentOffset); currentOffset += nameIndex.length; - //Top Dict Index - var topDictIndex = [ - 0x00, 0x01, 0x01, 0x01, 0x2A, - 248, 27, 0, // version - 248, 28, 1, // Notice - 248, 29, 2, // FullName - 248, 30, 3, // FamilyName - 248, 20, 4, // Weigth - 82, 251, 98, 250, 105, 249, 72, 5, // FontBBox - 248, 136, 15, // charset (offset: 500) - 28, 0, 0, 16, // Encoding - 28, 7, 208, 17, // CharStrings (offset: 2000) - 28, 0, 55, 28, 39, 16, 18 // Private (offset: 10000) - ]; - cff.set(topDictIndex, currentOffset); - currentOffset += topDictIndex.length; + // Calculate strings before writing the TopDICT index in order + // to calculate correct relative offsets for storing 'charset' + // and 'charstrings' data + var fontInfo = aFont.get("FontInfo"); + var version = fontInfo.get("version"); + var notice = fontInfo.get("Notice"); + var fullName = fontInfo.get("FullName"); + var familyName = fontInfo.get("FamilyName"); + var weight = fontInfo.get("Weight"); + var strings = [version, notice, fullName, + familyName, weight]; + var stringsIndex = this.createCFFIndexHeader(strings); + var stringsDataLength = stringsIndex.length; - // Strings Index - var stringsIndex = [ - 0x00, 0x04, 0x01, - 0x01, 0x05, 0x06, 0x07, 0x08, - 0x31, 0x2E, 0x030, 0x35, // 1.05 - 0x2B, // + - 0x28, // ( - 0x29 // ) - ]; - cff.set(stringsIndex, currentOffset); - currentOffset += stringsIndex.length; + // Create the global subroutines index + var globalSubrsIndex = this.createCFFIndexHeader([]); - - // Global Subrs Index - var globalSubrsIndex = [ - 0x00, 0x00, 0x00 - ]; - cff.set(globalSubrsIndex, currentOffset); - currentOffset += globalSubrsIndex.length; - - // Fill the space between this and the charset by '1' - var empty = new Array(500 - currentOffset); - for (var i = 0; i < empty.length; i++) - empty[i] = 0x01; - cff.set(empty, currentOffset); - currentOffset += empty.length; - - //Declare the letters - var charset = [ - 0x00 - ]; - for (var glyph in charstrings.map) { + // Fill the charset header (first byte is the encoding) + var charset = [0x00]; + for (var glyph in glyphs) { var index = CFFStrings.indexOf(glyph); var bytes = this.integerToBytes(index, 2); charset.push(bytes[0]); charset.push(bytes[1]); } - cff.set(charset, currentOffset); - currentOffset += charset.length; - - // Fill the space between this and the charstrings data by '1' - var empty = new Array(2000 - currentOffset); - for (var i = 0; i < empty.length; i++) - empty[i] = 0x01; - cff.set(empty, currentOffset); - currentOffset += empty.length; - + // Convert charstrings var getNumFor = { "hstem": 1, "vstem": 3, @@ -966,16 +914,64 @@ Type1Font.prototype = { r.push(charstring); } - var charStringsIndex = this.createCFFIndexHeader(r, true); - cff.set(charStringsIndex.join(" ").split(" "), currentOffset); - currentOffset += charStringsIndex.length; + var charstringsIndex = this.createCFFIndexHeader(r, true); + charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why? - // Fill the space between this and the private dict data by '1' - var empty = new Array(10000 - currentOffset); - for (var i = 0; i < empty.length; i++) - empty[i] = 0x01; - cff.set(empty, currentOffset); - currentOffset += empty.length; + + var fontBBox = aFont.get("FontBBox"); + + //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 + ]; + + 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(" "); + + // Top Dict Index + cff.set(topDictIndex, currentOffset); + currentOffset += topDictIndex.length; + + // Strings Index + cff.set(stringsIndex, currentOffset); + currentOffset += stringsIndex.length; + + // Global Subrs Index + cff.set(globalSubrsIndex, currentOffset); + currentOffset += globalSubrsIndex.length; + + // Charset Index + cff.set(charset, currentOffset); + currentOffset += charset.length; + + // Fill charstrings data + cff.set(charstringsIndex, currentOffset); + currentOffset += charstringsIndex.length; // Private Data var privateData = [ diff --git a/PDFFontUtils.js b/PDFFontUtils.js index e3b6a5a07..36dc2b421 100644 --- a/PDFFontUtils.js +++ b/PDFFontUtils.js @@ -277,16 +277,17 @@ var Type2Parser = function(aFilePath) { // 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); + log("TopDict: " + topDict); // Read the String Index dump("Reading Index: Strings"); var strings = readFontIndexData(aStream); - log(strings); + log("strings: " + strings); // Fill up the Strings dictionary with the new unique strings for (var i = 0; i < strings.length; i++) From 865b39336765007d82bedf967dddf195aa8ef106 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sat, 11 Jun 2011 03:25:58 +0200 Subject: [PATCH 23/77] Add a basic non-working OTF generator --- PDFFont.js | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 243 insertions(+), 1 deletion(-) diff --git a/PDFFont.js b/PDFFont.js index b616075e4..3dc4d4957 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -798,6 +798,13 @@ Type1Font.prototype = { return bytes; }, + bytesToInteger: function(aBytesArray) { + var value = 0; + for (var i = 0; i < aBytesArray.length; i++) + value = (value << 8) + aBytesArray[i]; + return value; + }, + encodeNumber: function(aValue) { var x = 0; // XXX we don't really care about Type2 optimization here... @@ -835,7 +842,7 @@ Type1Font.prototype = { charstringsCount++; charstringsDataLength += glyphs[glyph].length; } - log("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")"); + //log("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")"); // Create a CFF font data var cff = new Uint8Array(20000); @@ -1021,7 +1028,242 @@ Type1Font.prototype = { return data; }, + + createOpenTypeHeader: function(aNumTables) { + // sfnt version (4 bytes) + var version = [0x4F, 0x54, 0x54, 0X4F]; + + // numTables (2 bytes) + var numTables = aNumTables; + + // searchRange (2bytes) + // XXX oh man this is dirty, there's probably something obvious to do to + // quickly get the maximum power of 2 value... + var maxPower = 0; + var value = numTables; + while (value >= 2) { + value /= 2; + maxPower++; + } + + value = 2; + for (var i = 1; i < maxPower; i++) + value *= 2; + var searchRange = value * 16; + + // entrySelector (2 bytes) + var entrySelector = Math.log(value) / Math.log(2); + + // rangeShift (2 bytes) + var rangeShift = numTables * 16 - searchRange; + + return [].concat(version, + this.integerToBytes(numTables, 2), + this.integerToBytes(searchRange, 2), + this.integerToBytes(entrySelector, 2), + this.integerToBytes(rangeShift, 2)); + }, + + createTableEntry: function(aTag, aOffset, aData) { + // tag + var tag = [ + aTag.charCodeAt(0), + aTag.charCodeAt(1), + aTag.charCodeAt(2), + aTag.charCodeAt(3) + ]; + + // offset + var offset = aOffset; + + // length + var length = aData.length; + + // checksum + var checksum = this.bytesToInteger(tag) + offset + length; + + return [].concat(tag, + this.integerToBytes(checksum, 4), + this.integerToBytes(offset, 4), + this.integerToBytes(length, 4)); + }, + convertToOTF: function(aData, aFont) { + var otf = new Uint8Array(20000); + var currentOffset = 0; + + var header = this.createOpenTypeHeader(9); + otf.set(header, currentOffset); + currentOffset += header.length; + + var tablesLength = 9 * 16; + var virtualOffset = tablesLength + currentOffset; + var tableEntry = this.createTableEntry("CFF ", tablesLength + currentOffset, aData); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + + virtualOffset += aData.length; + + var 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 + 0x00, 0x00, 0x00, 0x01, // ulUnicodeRange1 (Bits 0-31) + 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange2 (Bits 32-63) + 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange3 (Bits 64-95) + 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange4 (Bits 96-127) + 0x47, 0x49, 0x60, 0x20, // achVendID + 0x00, 0x20, // fsSelection + 0x00, 0x2D, // usFirstCharIndex + 0x00, 0x7A, // usLastCharIndex + 0x03, // sTypoAscender + 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, // sxHeight + 0x00, // sCapHeight + 0x01, // usDefaultChar + 0xCD, // usBreakChar + 0x02 // usMaxContext + ]; + + var tableEntry = this.createTableEntry("OS/2", virtualOffset, OS2); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += OS2.length; + + var cmap = [ + 0x00, 0x00, // version + 0x00, 0x00 // numTables + ]; + + var tableEntry = this.createTableEntry("cmap", virtualOffset, cmap); + //otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += cmap.length; + + + var name = [ + 0x00, 0x00, // format + 0x00, 0x00, // Number of names Record + 0x00, 0x00 // Storage + ]; + + var tableEntry = this.createTableEntry("name", virtualOffset, name); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += name.length; + + + var hmtx = [ + 0x01, 0xF4, 0x00, + 0x00 + ]; + var tableEntry = this.createTableEntry("hmtx", virtualOffset, hmtx); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += hmtx.length; + + var maxp = [ + 0x00, 0x00, 0x50, 0x00, // Version number + 0x00, 0x01 // Nums of glyphs + ]; + var tableEntry = this.createTableEntry("maxp", virtualOffset, maxp); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += maxp.length; + + var 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 + 0x00, 0x00, // unitsPerEM + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // created + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // modified + 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 + ]; + var tableEntry = this.createTableEntry("head", virtualOffset, head); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += head.length; + + + var hhea = [ + 0x00, 0x01, 0x00, 0x00, // Version number + 0x00, 0x00, // Typographic Ascent + 0x00, 0x00, // Typographic Descent + 0x00, 0x00, // Line Gap + 0x01, 0xF4, // advanceWidthMax + 0x00, 0x00, // minLeftSidebearing + 0x00, 0x00, // minRightSidebearing + 0x00, 0x00, // xMaxExtent + 0x00, 0x00, // caretSlopeRise + 0x00, 0x00, // caretOffset + 0x00, 0x00, // -reserved- + 0x00, 0x00, // -reserved- + 0x00, 0x00, // -reserved- + 0x00, 0x00, // -reserved- + 0x00, 0x00, // metricDataFormat + 0x00, 0x01 // numberOfHMetrics + ]; + var tableEntry = this.createTableEntry("hhea", virtualOffset, hhea); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += hhea.length; + + + var post = [ + 0x00, 0x03, 0x00, 0x00, // Version number + 0x00, 0x00, 0x01, 0x00, // italicAngle + 0x00, 0x00, // underlinePosition + 0x00, 0x00, // underlineThickness + 0x00, 0x00, 0x00, 0x01, // isFixedPitch + 0x00, 0x00, 0x00, 0x00, // minMemType42 + 0x00, 0x00, 0x00, 0x00, // maxMemType42 + 0x00, 0x00, 0x00, 0x00, // minMemType1 + 0x00, 0x00, 0x00, 0x00 // maxMemType1 + ]; + var tableEntry = this.createTableEntry("post", virtualOffset, post); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += post.length; + + // Set the CFF data + otf.set(aData, currentOffset); + currentOffset += aData.length; + + var data = []; + for (var i = 0; i < currentOffset; i++) + data.push(otf[i]); + + writeToFile(data, "/tmp/pdf.js.otf"); } }; From 1c30621906d6cef79407215a1ad79d1374b06992 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sat, 11 Jun 2011 22:08:30 +0200 Subject: [PATCH 24/77] OTF does not complain anymore about a duplicate .notdef --- PDFFont.js | 183 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 123 insertions(+), 60 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 3dc4d4957..34011a9cf 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -736,8 +736,8 @@ Type1Font.prototype = { var defaultUsedCount = 0; var widths = {}; - for (var glyph in aCharstrings.map) { - var width = aCharstrings.get(glyph)[1]; + for (var i = 0; i < aCharstrings.length; i++) { + var width = aCharstrings[i].charstring[1]; var usedCount = (widths[width] || 0) + 1; if (usedCount > defaultUsedCount) { @@ -827,20 +827,45 @@ Type1Font.prototype = { } }, + getOrderedCharStrings: function(aFont) { + var dict = aFont.get("CharStrings") + var charstrings = []; + for (var glyph in dict.map) { + charstrings.push({ + glyph: glyph, + charstring: dict.map[glyph].slice() + }); + } + + charstrings.sort(function(a, b) { + return CFFStrings.indexOf(a.glyph) > CFFStrings.indexOf(b.glyph); + }); + charstrings.shift(); + + return charstrings; + }, + convertToCFF: function(aFont) { - var charstrings = aFont.get("CharStrings") + var charstrings = this.getOrderedCharStrings(aFont); var defaultWidth = this.getDefaultWidth(charstrings); var charstringsCount = 0; var charstringsDataLength = 0; - var glyphs = {}; + var glyphs = []; + var glyphsChecker = {}; var subrs = aFont.get("Private").get("Subrs"); var parser = new Type1Parser(); - for (var glyph in charstrings.map) { - var charstring = charstrings.get(glyph); - glyphs[glyph] = parser.flattenCharstring(charstring, defaultWidth, subrs); + for (var i = 0; i < charstrings.length; i++) { + var charstring = charstrings[i].charstring; + var glyph = charstrings[i].glyph; + if (glyphsChecker[glyph]) + error("glyphs already exists!"); + glyphsChecker[glyph] = true; + + var flattened = parser.flattenCharstring(charstring, defaultWidth, subrs); + glyphs.push(flattened); charstringsCount++; - charstringsDataLength += glyphs[glyph].length; + charstringsDataLength += flattened.length; } //log("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")"); @@ -877,8 +902,8 @@ Type1Font.prototype = { // Fill the charset header (first byte is the encoding) var charset = [0x00]; - for (var glyph in glyphs) { - var index = CFFStrings.indexOf(glyph); + for (var i = 0; i < glyphs.length; i++) { + var index = CFFStrings.indexOf(charstrings[i].glyph); var bytes = this.integerToBytes(index, 2); charset.push(bytes[0]); charset.push(bytes[1]); @@ -902,11 +927,11 @@ Type1Font.prototype = { // Encode the glyph and add it to the FUX var r = [[0x40, 0xEA]]; - for (var glyph in glyphs) { - var data = glyphs[glyph].slice(); + for (var i = 0; i < glyphs.length; i++) { + var data = glyphs[i].slice(); var charstring = []; - for (var i = 0; i < data.length; i++) { - var c = data[i]; + for (var j = 0; j < data.length; j++) { + var c = data[j]; if (!IsNum(c)) { var token = getNumFor[c]; if (!token) @@ -914,8 +939,8 @@ Type1Font.prototype = { charstring.push(token); } else { var bytes = this.encodeNumber(c); - for (var j = 0; j < bytes.length; j++) - charstring.push(bytes[j]); + for (var k = 0; k < bytes.length; k++) + charstring.push(bytes[k]); } } r.push(charstring); @@ -1092,16 +1117,16 @@ Type1Font.prototype = { var otf = new Uint8Array(20000); var currentOffset = 0; - var header = this.createOpenTypeHeader(9); + var numTables = 9; + var header = this.createOpenTypeHeader(numTables); otf.set(header, currentOffset); currentOffset += header.length; - var tablesLength = 9 * 16; - var virtualOffset = tablesLength + currentOffset; - var tableEntry = this.createTableEntry("CFF ", tablesLength + currentOffset, aData); + var baseOffset = numTables * (4 * 4) + currentOffset; + var virtualOffset = baseOffset; + var tableEntry = this.createTableEntry("CFF ", baseOffset, aData); otf.set(tableEntry, currentOffset); currentOffset += tableEntry.length; - virtualOffset += aData.length; var OS2 = [ @@ -1130,18 +1155,18 @@ Type1Font.prototype = { 0x00, 0x20, // fsSelection 0x00, 0x2D, // usFirstCharIndex 0x00, 0x7A, // usLastCharIndex - 0x03, // sTypoAscender - 0x20, // sTypeDescender + 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, // sxHeight - 0x00, // sCapHeight - 0x01, // usDefaultChar - 0xCD, // usBreakChar - 0x02 // usMaxContext + 0x00, 0x00, // sxHeight + 0x00, 0x00, // sCapHeight + 0x00, 0x01, // usDefaultChar + 0x00, 0xCD, // usBreakChar + 0x00, 0x02 // usMaxContext ]; var tableEntry = this.createTableEntry("OS/2", virtualOffset, OS2); @@ -1149,46 +1174,28 @@ Type1Font.prototype = { currentOffset += tableEntry.length; virtualOffset += OS2.length; + /** CMAP */ + var cmap = [ 0x00, 0x00, // version - 0x00, 0x00 // numTables + 0x00, 0x01, // numTables + 0x00, 0x03, // platformID + 0x00, 0x00, // encodingID + 0x00, 0x00, 0x00, 0x00, //offset + 0x00, 0x00, // format + 0x00, 0x40, // length + 0x00, 0x00, // language + 0x45, 0x46, 0x00, 0x45 ]; var tableEntry = this.createTableEntry("cmap", virtualOffset, cmap); - //otf.set(tableEntry, currentOffset); + otf.set(tableEntry, currentOffset); currentOffset += tableEntry.length; virtualOffset += cmap.length; + log(currentOffset + "::" + virtualOffset); - var name = [ - 0x00, 0x00, // format - 0x00, 0x00, // Number of names Record - 0x00, 0x00 // Storage - ]; - - var tableEntry = this.createTableEntry("name", virtualOffset, name); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += name.length; - - - var hmtx = [ - 0x01, 0xF4, 0x00, - 0x00 - ]; - var tableEntry = this.createTableEntry("hmtx", virtualOffset, hmtx); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += hmtx.length; - - var maxp = [ - 0x00, 0x00, 0x50, 0x00, // Version number - 0x00, 0x01 // Nums of glyphs - ]; - var tableEntry = this.createTableEntry("maxp", virtualOffset, maxp); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += maxp.length; + /** HEAD */ var head = [ 0x00, 0x01, 0x00, 0x00, // Version number @@ -1215,16 +1222,19 @@ Type1Font.prototype = { virtualOffset += head.length; + /** HHEA */ + var hhea = [ 0x00, 0x01, 0x00, 0x00, // Version number 0x00, 0x00, // Typographic Ascent 0x00, 0x00, // Typographic Descent 0x00, 0x00, // Line Gap - 0x01, 0xF4, // advanceWidthMax + 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- @@ -1238,6 +1248,52 @@ Type1Font.prototype = { currentOffset += tableEntry.length; virtualOffset += hhea.length; + /** HMTX */ + + var charstrings = this.getOrderedCharStrings(aFont); + var hmtx = [0x01, 0xF4, 0x00, 0x00]; + for (var i = 0; i < charstrings.length; i++) { + var charstring = charstrings[i].charstring; + var width = this.integerToBytes(charstring[1], 2); + var lsb = this.integerToBytes(charstring[0], 2); + hmtx.push(width[0]); + hmtx.push(width[1]); + hmtx.push(lsb[0]); + hmtx.push(lsb[1]); + } + + var tableEntry = this.createTableEntry("hmtx", virtualOffset, hmtx); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += hmtx.length; + + + /** MAXP */ + + var maxp = [ + 0x00, 0x00, 0x50, 0x00, // Version number + ].concat(this.integerToBytes(charstrings.length, 2)); // Num of glyphs + + var tableEntry = this.createTableEntry("maxp", virtualOffset, maxp); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += maxp.length; + + + /** NAME */ + + var name = [ + 0x00, 0x00, // format + 0x00, 0x00, // Number of names Record + 0x00, 0x00 // Storage + ]; + var tableEntry = this.createTableEntry("name", virtualOffset, name); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += name.length; + + + /** POST */ var post = [ 0x00, 0x03, 0x00, 0x00, // Version number @@ -1259,6 +1315,13 @@ Type1Font.prototype = { otf.set(aData, currentOffset); currentOffset += aData.length; + var tables = [OS2, cmap, hmtx, head, hhea, maxp, name, post]; + for (var i = 0; i < tables.length; i++) { + var table = tables[i]; + otf.set(table, currentOffset); + currentOffset += table.length; + } + var data = []; for (var i = 0; i < currentOffset; i++) data.push(otf[i]); From 667acb089c50d70f6638fef9b269c90ce3732102 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sat, 11 Jun 2011 22:36:18 +0200 Subject: [PATCH 25/77] OTF does not complain anymore about missize between the CFF data and the htmx table --- PDFFont.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 34011a9cf..33dd97866 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1124,7 +1124,7 @@ Type1Font.prototype = { var baseOffset = numTables * (4 * 4) + currentOffset; var virtualOffset = baseOffset; - var tableEntry = this.createTableEntry("CFF ", baseOffset, aData); + var tableEntry = this.createTableEntry("CFF ", virtualOffset, aData); otf.set(tableEntry, currentOffset); currentOffset += tableEntry.length; virtualOffset += aData.length; @@ -1192,7 +1192,6 @@ Type1Font.prototype = { otf.set(tableEntry, currentOffset); currentOffset += tableEntry.length; virtualOffset += cmap.length; - log(currentOffset + "::" + virtualOffset); /** HEAD */ @@ -1223,6 +1222,7 @@ Type1Font.prototype = { /** HHEA */ + var charstrings = this.getOrderedCharStrings(aFont); var hhea = [ 0x00, 0x01, 0x00, 0x00, // Version number @@ -1240,9 +1240,9 @@ Type1Font.prototype = { 0x00, 0x00, // -reserved- 0x00, 0x00, // -reserved- 0x00, 0x00, // -reserved- - 0x00, 0x00, // metricDataFormat - 0x00, 0x01 // numberOfHMetrics + 0x00, 0x00 // metricDataFormat ]; + hhea = hhea.concat(this.encodeNumber(charstrings.length, 2)); // numberOfHMetrics var tableEntry = this.createTableEntry("hhea", virtualOffset, hhea); otf.set(tableEntry, currentOffset); currentOffset += tableEntry.length; @@ -1250,16 +1250,13 @@ Type1Font.prototype = { /** HMTX */ - var charstrings = this.getOrderedCharStrings(aFont); var hmtx = [0x01, 0xF4, 0x00, 0x00]; for (var i = 0; i < charstrings.length; i++) { var charstring = charstrings[i].charstring; + log(charstrings[i].glyph + " " + charstring[1] + " :: " + charstring); var width = this.integerToBytes(charstring[1], 2); var lsb = this.integerToBytes(charstring[0], 2); - hmtx.push(width[0]); - hmtx.push(width[1]); - hmtx.push(lsb[0]); - hmtx.push(lsb[1]); + hmtx = hmtx.concat(width, lsb); } var tableEntry = this.createTableEntry("hmtx", virtualOffset, hmtx); @@ -1315,12 +1312,13 @@ Type1Font.prototype = { otf.set(aData, currentOffset); currentOffset += aData.length; - var tables = [OS2, cmap, hmtx, head, hhea, maxp, name, post]; + var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post]; for (var i = 0; i < tables.length; i++) { var table = tables[i]; otf.set(table, currentOffset); currentOffset += table.length; } + log(currentOffset + "::" + virtualOffset + "\n"); var data = []; for (var i = 0; i < currentOffset; i++) From e0beef4e252049273703efa4c6f8cc90662bffaf Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 00:54:47 +0200 Subject: [PATCH 26/77] No more errors for an empty unicode table --- PDFFont.js | 28 +- glyphlist.js | 4283 ++++++++++++++++++++++++++++++++++++++++++++++++++ test.html | 1 + 3 files changed, 4304 insertions(+), 8 deletions(-) create mode 100644 glyphlist.js diff --git a/PDFFont.js b/PDFFont.js index 33dd97866..0eb29d323 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1175,19 +1175,33 @@ Type1Font.prototype = { virtualOffset += OS2.length; /** CMAP */ + var charstrings = this.getOrderedCharStrings(aFont); var cmap = [ 0x00, 0x00, // version 0x00, 0x01, // numTables - 0x00, 0x03, // platformID + 0x00, 0x01, // platformID 0x00, 0x00, // encodingID - 0x00, 0x00, 0x00, 0x00, //offset - 0x00, 0x00, // format - 0x00, 0x40, // length - 0x00, 0x00, // language - 0x45, 0x46, 0x00, 0x45 + 0x00, 0x00, 0x00, 0x0C, //offset + 0x00, 0x00, + 0x01, 0x06, + 0x00, 0x00 ]; + var data = []; + for (var i = 0; i < 262; i++) { + data.push(0x00); + } + + for (var i = 0; i < charstrings.length; i++) { + var pos = GlyphsUnicode[charstrings[i].glyph]; + var b1 = parseInt("0x" + pos[0] + pos[1]); + var b2 = parseInt("0x" + pos[2] + pos[3]); + var pos = this.bytesToInteger([b1, b2]); + data[pos] = i + 1; + } + cmap = cmap.concat(data); + var tableEntry = this.createTableEntry("cmap", virtualOffset, cmap); otf.set(tableEntry, currentOffset); currentOffset += tableEntry.length; @@ -1222,7 +1236,6 @@ Type1Font.prototype = { /** HHEA */ - var charstrings = this.getOrderedCharStrings(aFont); var hhea = [ 0x00, 0x01, 0x00, 0x00, // Version number @@ -1253,7 +1266,6 @@ Type1Font.prototype = { var hmtx = [0x01, 0xF4, 0x00, 0x00]; for (var i = 0; i < charstrings.length; i++) { var charstring = charstrings[i].charstring; - log(charstrings[i].glyph + " " + charstring[1] + " :: " + charstring); var width = this.integerToBytes(charstring[1], 2); var lsb = this.integerToBytes(charstring[0], 2); hmtx = hmtx.concat(width, lsb); diff --git a/glyphlist.js b/glyphlist.js new file mode 100644 index 000000000..de07af4a5 --- /dev/null +++ b/glyphlist.js @@ -0,0 +1,4283 @@ +var GlyphsUnicode = { + A: "0041", + AE: "00C6", + AEacute: "01FC", + AEmacron: "01E2", + AEsmall: "F7E6", + Aacute: "00C1", + Aacutesmall: "F7E1", + Abreve: "0102", + Abreveacute: "1EAE", + Abrevecyrillic: "04D0", + Abrevedotbelow: "1EB6", + Abrevegrave: "1EB0", + Abrevehookabove: "1EB2", + Abrevetilde: "1EB4", + Acaron: "01CD", + Acircle: "24B6", + Acircumflex: "00C2", + Acircumflexacute: "1EA4", + Acircumflexdotbelow: "1EAC", + Acircumflexgrave: "1EA6", + Acircumflexhookabove: "1EA8", + Acircumflexsmall: "F7E2", + Acircumflextilde: "1EAA", + Acute: "F6C9", + Acutesmall: "F7B4", + Acyrillic: "0410", + Adblgrave: "0200", + Adieresis: "00C4", + Adieresiscyrillic: "04D2", + Adieresismacron: "01DE", + Adieresissmall: "F7E4", + Adotbelow: "1EA0", + Adotmacron: "01E0", + Agrave: "00C0", + Agravesmall: "F7E0", + Ahookabove: "1EA2", + Aiecyrillic: "04D4", + Ainvertedbreve: "0202", + Alpha: "0391", + Alphatonos: "0386", + Amacron: "0100", + Amonospace: "FF21", + Aogonek: "0104", + Aring: "00C5", + Aringacute: "01FA", + Aringbelow: "1E00", + Aringsmall: "F7E5", + Asmall: "F761", + Atilde: "00C3", + Atildesmall: "F7E3", + Aybarmenian: "0531", + B: "0042", + Bcircle: "24B7", + Bdotaccent: "1E02", + Bdotbelow: "1E04", + Becyrillic: "0411", + Benarmenian: "0532", + Beta: "0392", + Bhook: "0181", + Blinebelow: "1E06", + Bmonospace: "FF22", + Brevesmall: "F6F4", + Bsmall: "F762", + Btopbar: "0182", + C: "0043", + Caarmenian: "053E", + Cacute: "0106", + Caron: "F6CA", + Caronsmall: "F6F5", + Ccaron: "010C", + Ccedilla: "00C7", + Ccedillaacute: "1E08", + Ccedillasmall: "F7E7", + Ccircle: "24B8", + Ccircumflex: "0108", + Cdot: "010A", + Cdotaccent: "010A", + Cedillasmall: "F7B8", + Chaarmenian: "0549", + Cheabkhasiancyrillic: "04BC", + Checyrillic: "0427", + Chedescenderabkhasiancyrillic: "04BE", + Chedescendercyrillic: "04B6", + Chedieresiscyrillic: "04F4", + Cheharmenian: "0543", + Chekhakassiancyrillic: "04CB", + Cheverticalstrokecyrillic: "04B8", + Chi: "03A7", + Chook: "0187", + Circumflexsmall: "F6F6", + Cmonospace: "FF23", + Coarmenian: "0551", + Csmall: "F763", + D: "0044", + DZ: "01F1", + DZcaron: "01C4", + Daarmenian: "0534", + Dafrican: "0189", + Dcaron: "010E", + Dcedilla: "1E10", + Dcircle: "24B9", + Dcircumflexbelow: "1E12", + Dcroat: "0110", + Ddotaccent: "1E0A", + Ddotbelow: "1E0C", + Decyrillic: "0414", + Deicoptic: "03EE", + Delta: "2206", + Deltagreek: "0394", + Dhook: "018A", + Dieresis: "F6CB", + DieresisAcute: "F6CC", + DieresisGrave: "F6CD", + Dieresissmall: "F7A8", + Digammagreek: "03DC", + Djecyrillic: "0402", + Dlinebelow: "1E0E", + Dmonospace: "FF24", + Dotaccentsmall: "F6F7", + Dslash: "0110", + Dsmall: "F764", + Dtopbar: "018B", + Dz: "01F2", + Dzcaron: "01C5", + Dzeabkhasiancyrillic: "04E0", + Dzecyrillic: "0405", + Dzhecyrillic: "040F", + E: "0045", + Eacute: "00C9", + Eacutesmall: "F7E9", + Ebreve: "0114", + Ecaron: "011A", + Ecedillabreve: "1E1C", + Echarmenian: "0535", + Ecircle: "24BA", + Ecircumflex: "00CA", + Ecircumflexacute: "1EBE", + Ecircumflexbelow: "1E18", + Ecircumflexdotbelow: "1EC6", + Ecircumflexgrave: "1EC0", + Ecircumflexhookabove: "1EC2", + Ecircumflexsmall: "F7EA", + Ecircumflextilde: "1EC4", + Ecyrillic: "0404", + Edblgrave: "0204", + Edieresis: "00CB", + Edieresissmall: "F7EB", + Edot: "0116", + Edotaccent: "0116", + Edotbelow: "1EB8", + Efcyrillic: "0424", + Egrave: "00C8", + Egravesmall: "F7E8", + Eharmenian: "0537", + Ehookabove: "1EBA", + Eightroman: "2167", + Einvertedbreve: "0206", + Eiotifiedcyrillic: "0464", + Elcyrillic: "041B", + Elevenroman: "216A", + Emacron: "0112", + Emacronacute: "1E16", + Emacrongrave: "1E14", + Emcyrillic: "041C", + Emonospace: "FF25", + Encyrillic: "041D", + Endescendercyrillic: "04A2", + Eng: "014A", + Enghecyrillic: "04A4", + Enhookcyrillic: "04C7", + Eogonek: "0118", + Eopen: "0190", + Epsilon: "0395", + Epsilontonos: "0388", + Ercyrillic: "0420", + Ereversed: "018E", + Ereversedcyrillic: "042D", + Escyrillic: "0421", + Esdescendercyrillic: "04AA", + Esh: "01A9", + Esmall: "F765", + Eta: "0397", + Etarmenian: "0538", + Etatonos: "0389", + Eth: "00D0", + Ethsmall: "F7F0", + Etilde: "1EBC", + Etildebelow: "1E1A", + Euro: "20AC", + Ezh: "01B7", + Ezhcaron: "01EE", + Ezhreversed: "01B8", + F: "0046", + Fcircle: "24BB", + Fdotaccent: "1E1E", + Feharmenian: "0556", + Feicoptic: "03E4", + Fhook: "0191", + Fitacyrillic: "0472", + Fiveroman: "2164", + Fmonospace: "FF26", + Fourroman: "2163", + Fsmall: "F766", + G: "0047", + GBsquare: "3387", + Gacute: "01F4", + Gamma: "0393", + Gammaafrican: "0194", + Gangiacoptic: "03EA", + Gbreve: "011E", + Gcaron: "01E6", + Gcedilla: "0122", + Gcircle: "24BC", + Gcircumflex: "011C", + Gcommaaccent: "0122", + Gdot: "0120", + Gdotaccent: "0120", + Gecyrillic: "0413", + Ghadarmenian: "0542", + Ghemiddlehookcyrillic: "0494", + Ghestrokecyrillic: "0492", + Gheupturncyrillic: "0490", + Ghook: "0193", + Gimarmenian: "0533", + Gjecyrillic: "0403", + Gmacron: "1E20", + Gmonospace: "FF27", + Grave: "F6CE", + Gravesmall: "F760", + Gsmall: "F767", + Gsmallhook: "029B", + Gstroke: "01E4", + H: "0048", + H18533: "25CF", + H18543: "25AA", + H18551: "25AB", + H22073: "25A1", + HPsquare: "33CB", + Haabkhasiancyrillic: "04A8", + Hadescendercyrillic: "04B2", + Hardsigncyrillic: "042A", + Hbar: "0126", + Hbrevebelow: "1E2A", + Hcedilla: "1E28", + Hcircle: "24BD", + Hcircumflex: "0124", + Hdieresis: "1E26", + Hdotaccent: "1E22", + Hdotbelow: "1E24", + Hmonospace: "FF28", + Hoarmenian: "0540", + Horicoptic: "03E8", + Hsmall: "F768", + Hungarumlaut: "F6CF", + Hungarumlautsmall: "F6F8", + Hzsquare: "3390", + I: "0049", + IAcyrillic: "042F", + IJ: "0132", + IUcyrillic: "042E", + Iacute: "00CD", + Iacutesmall: "F7ED", + Ibreve: "012C", + Icaron: "01CF", + Icircle: "24BE", + Icircumflex: "00CE", + Icircumflexsmall: "F7EE", + Icyrillic: "0406", + Idblgrave: "0208", + Idieresis: "00CF", + Idieresisacute: "1E2E", + Idieresiscyrillic: "04E4", + Idieresissmall: "F7EF", + Idot: "0130", + Idotaccent: "0130", + Idotbelow: "1ECA", + Iebrevecyrillic: "04D6", + Iecyrillic: "0415", + Ifraktur: "2111", + Igrave: "00CC", + Igravesmall: "F7EC", + Ihookabove: "1EC8", + Iicyrillic: "0418", + Iinvertedbreve: "020A", + Iishortcyrillic: "0419", + Imacron: "012A", + Imacroncyrillic: "04E2", + Imonospace: "FF29", + Iniarmenian: "053B", + Iocyrillic: "0401", + Iogonek: "012E", + Iota: "0399", + Iotaafrican: "0196", + Iotadieresis: "03AA", + Iotatonos: "038A", + Ismall: "F769", + Istroke: "0197", + Itilde: "0128", + Itildebelow: "1E2C", + Izhitsacyrillic: "0474", + Izhitsadblgravecyrillic: "0476", + J: "004A", + Jaarmenian: "0541", + Jcircle: "24BF", + Jcircumflex: "0134", + Jecyrillic: "0408", + Jheharmenian: "054B", + Jmonospace: "FF2A", + Jsmall: "F76A", + K: "004B", + KBsquare: "3385", + KKsquare: "33CD", + Kabashkircyrillic: "04A0", + Kacute: "1E30", + Kacyrillic: "041A", + Kadescendercyrillic: "049A", + Kahookcyrillic: "04C3", + Kappa: "039A", + Kastrokecyrillic: "049E", + Kaverticalstrokecyrillic: "049C", + Kcaron: "01E8", + Kcedilla: "0136", + Kcircle: "24C0", + Kcommaaccent: "0136", + Kdotbelow: "1E32", + Keharmenian: "0554", + Kenarmenian: "053F", + Khacyrillic: "0425", + Kheicoptic: "03E6", + Khook: "0198", + Kjecyrillic: "040C", + Klinebelow: "1E34", + Kmonospace: "FF2B", + Koppacyrillic: "0480", + Koppagreek: "03DE", + Ksicyrillic: "046E", + Ksmall: "F76B", + L: "004C", + LJ: "01C7", + LL: "F6BF", + Lacute: "0139", + Lambda: "039B", + Lcaron: "013D", + Lcedilla: "013B", + Lcircle: "24C1", + Lcircumflexbelow: "1E3C", + Lcommaaccent: "013B", + Ldot: "013F", + Ldotaccent: "013F", + Ldotbelow: "1E36", + Ldotbelowmacron: "1E38", + Liwnarmenian: "053C", + Lj: "01C8", + Ljecyrillic: "0409", + Llinebelow: "1E3A", + Lmonospace: "FF2C", + Lslash: "0141", + Lslashsmall: "F6F9", + Lsmall: "F76C", + M: "004D", + MBsquare: "3386", + Macron: "F6D0", + Macronsmall: "F7AF", + Macute: "1E3E", + Mcircle: "24C2", + Mdotaccent: "1E40", + Mdotbelow: "1E42", + Menarmenian: "0544", + Mmonospace: "FF2D", + Msmall: "F76D", + Mturned: "019C", + Mu: "039C", + N: "004E", + NJ: "01CA", + Nacute: "0143", + Ncaron: "0147", + Ncedilla: "0145", + Ncircle: "24C3", + Ncircumflexbelow: "1E4A", + Ncommaaccent: "0145", + Ndotaccent: "1E44", + Ndotbelow: "1E46", + Nhookleft: "019D", + Nineroman: "2168", + Nj: "01CB", + Njecyrillic: "040A", + Nlinebelow: "1E48", + Nmonospace: "FF2E", + Nowarmenian: "0546", + Nsmall: "F76E", + Ntilde: "00D1", + Ntildesmall: "F7F1", + Nu: "039D", + O: "004F", + OE: "0152", + OEsmall: "F6FA", + Oacute: "00D3", + Oacutesmall: "F7F3", + Obarredcyrillic: "04E8", + Obarreddieresiscyrillic: "04EA", + Obreve: "014E", + Ocaron: "01D1", + Ocenteredtilde: "019F", + Ocircle: "24C4", + Ocircumflex: "00D4", + Ocircumflexacute: "1ED0", + Ocircumflexdotbelow: "1ED8", + Ocircumflexgrave: "1ED2", + Ocircumflexhookabove: "1ED4", + Ocircumflexsmall: "F7F4", + Ocircumflextilde: "1ED6", + Ocyrillic: "041E", + Odblacute: "0150", + Odblgrave: "020C", + Odieresis: "00D6", + Odieresiscyrillic: "04E6", + Odieresissmall: "F7F6", + Odotbelow: "1ECC", + Ogoneksmall: "F6FB", + Ograve: "00D2", + Ogravesmall: "F7F2", + Oharmenian: "0555", + Ohm: "2126", + Ohookabove: "1ECE", + Ohorn: "01A0", + Ohornacute: "1EDA", + Ohorndotbelow: "1EE2", + Ohorngrave: "1EDC", + Ohornhookabove: "1EDE", + Ohorntilde: "1EE0", + Ohungarumlaut: "0150", + Oi: "01A2", + Oinvertedbreve: "020E", + Omacron: "014C", + Omacronacute: "1E52", + Omacrongrave: "1E50", + Omega: "2126", + Omegacyrillic: "0460", + Omegagreek: "03A9", + Omegaroundcyrillic: "047A", + Omegatitlocyrillic: "047C", + Omegatonos: "038F", + Omicron: "039F", + Omicrontonos: "038C", + Omonospace: "FF2F", + Oneroman: "2160", + Oogonek: "01EA", + Oogonekmacron: "01EC", + Oopen: "0186", + Oslash: "00D8", + Oslashacute: "01FE", + Oslashsmall: "F7F8", + Osmall: "F76F", + Ostrokeacute: "01FE", + Otcyrillic: "047E", + Otilde: "00D5", + Otildeacute: "1E4C", + Otildedieresis: "1E4E", + Otildesmall: "F7F5", + P: "0050", + Pacute: "1E54", + Pcircle: "24C5", + Pdotaccent: "1E56", + Pecyrillic: "041F", + Peharmenian: "054A", + Pemiddlehookcyrillic: "04A6", + Phi: "03A6", + Phook: "01A4", + Pi: "03A0", + Piwrarmenian: "0553", + Pmonospace: "FF30", + Psi: "03A8", + Psicyrillic: "0470", + Psmall: "F770", + Q: "0051", + Qcircle: "24C6", + Qmonospace: "FF31", + Qsmall: "F771", + R: "0052", + Raarmenian: "054C", + Racute: "0154", + Rcaron: "0158", + Rcedilla: "0156", + Rcircle: "24C7", + Rcommaaccent: "0156", + Rdblgrave: "0210", + Rdotaccent: "1E58", + Rdotbelow: "1E5A", + Rdotbelowmacron: "1E5C", + Reharmenian: "0550", + Rfraktur: "211C", + Rho: "03A1", + Ringsmall: "F6FC", + Rinvertedbreve: "0212", + Rlinebelow: "1E5E", + Rmonospace: "FF32", + Rsmall: "F772", + Rsmallinverted: "0281", + Rsmallinvertedsuperior: "02B6", + S: "0053", + SF010000: "250C", + SF020000: "2514", + SF030000: "2510", + SF040000: "2518", + SF050000: "253C", + SF060000: "252C", + SF070000: "2534", + SF080000: "251C", + SF090000: "2524", + SF100000: "2500", + SF110000: "2502", + SF190000: "2561", + SF200000: "2562", + SF210000: "2556", + SF220000: "2555", + SF230000: "2563", + SF240000: "2551", + SF250000: "2557", + SF260000: "255D", + SF270000: "255C", + SF280000: "255B", + SF360000: "255E", + SF370000: "255F", + SF380000: "255A", + SF390000: "2554", + SF400000: "2569", + SF410000: "2566", + SF420000: "2560", + SF430000: "2550", + SF440000: "256C", + SF450000: "2567", + SF460000: "2568", + SF470000: "2564", + SF480000: "2565", + SF490000: "2559", + SF500000: "2558", + SF510000: "2552", + SF520000: "2553", + SF530000: "256B", + SF540000: "256A", + Sacute: "015A", + Sacutedotaccent: "1E64", + Sampigreek: "03E0", + Scaron: "0160", + Scarondotaccent: "1E66", + Scaronsmall: "F6FD", + Scedilla: "015E", + Schwa: "018F", + Schwacyrillic: "04D8", + Schwadieresiscyrillic: "04DA", + Scircle: "24C8", + Scircumflex: "015C", + Scommaaccent: "0218", + Sdotaccent: "1E60", + Sdotbelow: "1E62", + Sdotbelowdotaccent: "1E68", + Seharmenian: "054D", + Sevenroman: "2166", + Shaarmenian: "0547", + Shacyrillic: "0428", + Shchacyrillic: "0429", + Sheicoptic: "03E2", + Shhacyrillic: "04BA", + Shimacoptic: "03EC", + Sigma: "03A3", + Sixroman: "2165", + Smonospace: "FF33", + Softsigncyrillic: "042C", + Ssmall: "F773", + Stigmagreek: "03DA", + T: "0054", + Tau: "03A4", + Tbar: "0166", + Tcaron: "0164", + Tcedilla: "0162", + Tcircle: "24C9", + Tcircumflexbelow: "1E70", + Tcommaaccent: "0162", + Tdotaccent: "1E6A", + Tdotbelow: "1E6C", + Tecyrillic: "0422", + Tedescendercyrillic: "04AC", + Tenroman: "2169", + Tetsecyrillic: "04B4", + Theta: "0398", + Thook: "01AC", + Thorn: "00DE", + Thornsmall: "F7FE", + Threeroman: "2162", + Tildesmall: "F6FE", + Tiwnarmenian: "054F", + Tlinebelow: "1E6E", + Tmonospace: "FF34", + Toarmenian: "0539", + Tonefive: "01BC", + Tonesix: "0184", + Tonetwo: "01A7", + Tretroflexhook: "01AE", + Tsecyrillic: "0426", + Tshecyrillic: "040B", + Tsmall: "F774", + Twelveroman: "216B", + Tworoman: "2161", + U: "0055", + Uacute: "00DA", + Uacutesmall: "F7FA", + Ubreve: "016C", + Ucaron: "01D3", + Ucircle: "24CA", + Ucircumflex: "00DB", + Ucircumflexbelow: "1E76", + Ucircumflexsmall: "F7FB", + Ucyrillic: "0423", + Udblacute: "0170", + Udblgrave: "0214", + Udieresis: "00DC", + Udieresisacute: "01D7", + Udieresisbelow: "1E72", + Udieresiscaron: "01D9", + Udieresiscyrillic: "04F0", + Udieresisgrave: "01DB", + Udieresismacron: "01D5", + Udieresissmall: "F7FC", + Udotbelow: "1EE4", + Ugrave: "00D9", + Ugravesmall: "F7F9", + Uhookabove: "1EE6", + Uhorn: "01AF", + Uhornacute: "1EE8", + Uhorndotbelow: "1EF0", + Uhorngrave: "1EEA", + Uhornhookabove: "1EEC", + Uhorntilde: "1EEE", + Uhungarumlaut: "0170", + Uhungarumlautcyrillic: "04F2", + Uinvertedbreve: "0216", + Ukcyrillic: "0478", + Umacron: "016A", + Umacroncyrillic: "04EE", + Umacrondieresis: "1E7A", + Umonospace: "FF35", + Uogonek: "0172", + Upsilon: "03A5", + Upsilon1: "03D2", + Upsilonacutehooksymbolgreek: "03D3", + Upsilonafrican: "01B1", + Upsilondieresis: "03AB", + Upsilondieresishooksymbolgreek: "03D4", + Upsilonhooksymbol: "03D2", + Upsilontonos: "038E", + Uring: "016E", + Ushortcyrillic: "040E", + Usmall: "F775", + Ustraightcyrillic: "04AE", + Ustraightstrokecyrillic: "04B0", + Utilde: "0168", + Utildeacute: "1E78", + Utildebelow: "1E74", + V: "0056", + Vcircle: "24CB", + Vdotbelow: "1E7E", + Vecyrillic: "0412", + Vewarmenian: "054E", + Vhook: "01B2", + Vmonospace: "FF36", + Voarmenian: "0548", + Vsmall: "F776", + Vtilde: "1E7C", + W: "0057", + Wacute: "1E82", + Wcircle: "24CC", + Wcircumflex: "0174", + Wdieresis: "1E84", + Wdotaccent: "1E86", + Wdotbelow: "1E88", + Wgrave: "1E80", + Wmonospace: "FF37", + Wsmall: "F777", + X: "0058", + Xcircle: "24CD", + Xdieresis: "1E8C", + Xdotaccent: "1E8A", + Xeharmenian: "053D", + Xi: "039E", + Xmonospace: "FF38", + Xsmall: "F778", + Y: "0059", + Yacute: "00DD", + Yacutesmall: "F7FD", + Yatcyrillic: "0462", + Ycircle: "24CE", + Ycircumflex: "0176", + Ydieresis: "0178", + Ydieresissmall: "F7FF", + Ydotaccent: "1E8E", + Ydotbelow: "1EF4", + Yericyrillic: "042B", + Yerudieresiscyrillic: "04F8", + Ygrave: "1EF2", + Yhook: "01B3", + Yhookabove: "1EF6", + Yiarmenian: "0545", + Yicyrillic: "0407", + Yiwnarmenian: "0552", + Ymonospace: "FF39", + Ysmall: "F779", + Ytilde: "1EF8", + Yusbigcyrillic: "046A", + Yusbigiotifiedcyrillic: "046C", + Yuslittlecyrillic: "0466", + Yuslittleiotifiedcyrillic: "0468", + Z: "005A", + Zaarmenian: "0536", + Zacute: "0179", + Zcaron: "017D", + Zcaronsmall: "F6FF", + Zcircle: "24CF", + Zcircumflex: "1E90", + Zdot: "017B", + Zdotaccent: "017B", + Zdotbelow: "1E92", + Zecyrillic: "0417", + Zedescendercyrillic: "0498", + Zedieresiscyrillic: "04DE", + Zeta: "0396", + Zhearmenian: "053A", + Zhebrevecyrillic: "04C1", + Zhecyrillic: "0416", + Zhedescendercyrillic: "0496", + Zhedieresiscyrillic: "04DC", + Zlinebelow: "1E94", + Zmonospace: "FF3A", + Zsmall: "F77A", + Zstroke: "01B5", + a: "0061", + aabengali: "0986", + aacute: "00E1", + aadeva: "0906", + aagujarati: "0A86", + aagurmukhi: "0A06", + aamatragurmukhi: "0A3E", + aarusquare: "3303", + aavowelsignbengali: "09BE", + aavowelsigndeva: "093E", + aavowelsigngujarati: "0ABE", + abbreviationmarkarmenian: "055F", + abbreviationsigndeva: "0970", + abengali: "0985", + abopomofo: "311A", + abreve: "0103", + abreveacute: "1EAF", + abrevecyrillic: "04D1", + abrevedotbelow: "1EB7", + abrevegrave: "1EB1", + abrevehookabove: "1EB3", + abrevetilde: "1EB5", + acaron: "01CE", + acircle: "24D0", + acircumflex: "00E2", + acircumflexacute: "1EA5", + acircumflexdotbelow: "1EAD", + acircumflexgrave: "1EA7", + acircumflexhookabove: "1EA9", + acircumflextilde: "1EAB", + acute: "00B4", + acutebelowcmb: "0317", + acutecmb: "0301", + acutecomb: "0301", + acutedeva: "0954", + acutelowmod: "02CF", + acutetonecmb: "0341", + acyrillic: "0430", + adblgrave: "0201", + addakgurmukhi: "0A71", + adeva: "0905", + adieresis: "00E4", + adieresiscyrillic: "04D3", + adieresismacron: "01DF", + adotbelow: "1EA1", + adotmacron: "01E1", + ae: "00E6", + aeacute: "01FD", + aekorean: "3150", + aemacron: "01E3", + afii00208: "2015", + afii08941: "20A4", + afii10017: "0410", + afii10018: "0411", + afii10019: "0412", + afii10020: "0413", + afii10021: "0414", + afii10022: "0415", + afii10023: "0401", + afii10024: "0416", + afii10025: "0417", + afii10026: "0418", + afii10027: "0419", + afii10028: "041A", + afii10029: "041B", + afii10030: "041C", + afii10031: "041D", + afii10032: "041E", + afii10033: "041F", + afii10034: "0420", + afii10035: "0421", + afii10036: "0422", + afii10037: "0423", + afii10038: "0424", + afii10039: "0425", + afii10040: "0426", + afii10041: "0427", + afii10042: "0428", + afii10043: "0429", + afii10044: "042A", + afii10045: "042B", + afii10046: "042C", + afii10047: "042D", + afii10048: "042E", + afii10049: "042F", + afii10050: "0490", + afii10051: "0402", + afii10052: "0403", + afii10053: "0404", + afii10054: "0405", + afii10055: "0406", + afii10056: "0407", + afii10057: "0408", + afii10058: "0409", + afii10059: "040A", + afii10060: "040B", + afii10061: "040C", + afii10062: "040E", + afii10063: "F6C4", + afii10064: "F6C5", + afii10065: "0430", + afii10066: "0431", + afii10067: "0432", + afii10068: "0433", + afii10069: "0434", + afii10070: "0435", + afii10071: "0451", + afii10072: "0436", + afii10073: "0437", + afii10074: "0438", + afii10075: "0439", + afii10076: "043A", + afii10077: "043B", + afii10078: "043C", + afii10079: "043D", + afii10080: "043E", + afii10081: "043F", + afii10082: "0440", + afii10083: "0441", + afii10084: "0442", + afii10085: "0443", + afii10086: "0444", + afii10087: "0445", + afii10088: "0446", + afii10089: "0447", + afii10090: "0448", + afii10091: "0449", + afii10092: "044A", + afii10093: "044B", + afii10094: "044C", + afii10095: "044D", + afii10096: "044E", + afii10097: "044F", + afii10098: "0491", + afii10099: "0452", + afii10100: "0453", + afii10101: "0454", + afii10102: "0455", + afii10103: "0456", + afii10104: "0457", + afii10105: "0458", + afii10106: "0459", + afii10107: "045A", + afii10108: "045B", + afii10109: "045C", + afii10110: "045E", + afii10145: "040F", + afii10146: "0462", + afii10147: "0472", + afii10148: "0474", + afii10192: "F6C6", + afii10193: "045F", + afii10194: "0463", + afii10195: "0473", + afii10196: "0475", + afii10831: "F6C7", + afii10832: "F6C8", + afii10846: "04D9", + afii299: "200E", + afii300: "200F", + afii301: "200D", + afii57381: "066A", + afii57388: "060C", + afii57392: "0660", + afii57393: "0661", + afii57394: "0662", + afii57395: "0663", + afii57396: "0664", + afii57397: "0665", + afii57398: "0666", + afii57399: "0667", + afii57400: "0668", + afii57401: "0669", + afii57403: "061B", + afii57407: "061F", + afii57409: "0621", + afii57410: "0622", + afii57411: "0623", + afii57412: "0624", + afii57413: "0625", + afii57414: "0626", + afii57415: "0627", + afii57416: "0628", + afii57417: "0629", + afii57418: "062A", + afii57419: "062B", + afii57420: "062C", + afii57421: "062D", + afii57422: "062E", + afii57423: "062F", + afii57424: "0630", + afii57425: "0631", + afii57426: "0632", + afii57427: "0633", + afii57428: "0634", + afii57429: "0635", + afii57430: "0636", + afii57431: "0637", + afii57432: "0638", + afii57433: "0639", + afii57434: "063A", + afii57440: "0640", + afii57441: "0641", + afii57442: "0642", + afii57443: "0643", + afii57444: "0644", + afii57445: "0645", + afii57446: "0646", + afii57448: "0648", + afii57449: "0649", + afii57450: "064A", + afii57451: "064B", + afii57452: "064C", + afii57453: "064D", + afii57454: "064E", + afii57455: "064F", + afii57456: "0650", + afii57457: "0651", + afii57458: "0652", + afii57470: "0647", + afii57505: "06A4", + afii57506: "067E", + afii57507: "0686", + afii57508: "0698", + afii57509: "06AF", + afii57511: "0679", + afii57512: "0688", + afii57513: "0691", + afii57514: "06BA", + afii57519: "06D2", + afii57534: "06D5", + afii57636: "20AA", + afii57645: "05BE", + afii57658: "05C3", + afii57664: "05D0", + afii57665: "05D1", + afii57666: "05D2", + afii57667: "05D3", + afii57668: "05D4", + afii57669: "05D5", + afii57670: "05D6", + afii57671: "05D7", + afii57672: "05D8", + afii57673: "05D9", + afii57674: "05DA", + afii57675: "05DB", + afii57676: "05DC", + afii57677: "05DD", + afii57678: "05DE", + afii57679: "05DF", + afii57680: "05E0", + afii57681: "05E1", + afii57682: "05E2", + afii57683: "05E3", + afii57684: "05E4", + afii57685: "05E5", + afii57686: "05E6", + afii57687: "05E7", + afii57688: "05E8", + afii57689: "05E9", + afii57690: "05EA", + afii57694: "FB2A", + afii57695: "FB2B", + afii57700: "FB4B", + afii57705: "FB1F", + afii57716: "05F0", + afii57717: "05F1", + afii57718: "05F2", + afii57723: "FB35", + afii57793: "05B4", + afii57794: "05B5", + afii57795: "05B6", + afii57796: "05BB", + afii57797: "05B8", + afii57798: "05B7", + afii57799: "05B0", + afii57800: "05B2", + afii57801: "05B1", + afii57802: "05B3", + afii57803: "05C2", + afii57804: "05C1", + afii57806: "05B9", + afii57807: "05BC", + afii57839: "05BD", + afii57841: "05BF", + afii57842: "05C0", + afii57929: "02BC", + afii61248: "2105", + afii61289: "2113", + afii61352: "2116", + afii61573: "202C", + afii61574: "202D", + afii61575: "202E", + afii61664: "200C", + afii63167: "066D", + afii64937: "02BD", + agrave: "00E0", + agujarati: "0A85", + agurmukhi: "0A05", + ahiragana: "3042", + ahookabove: "1EA3", + aibengali: "0990", + aibopomofo: "311E", + aideva: "0910", + aiecyrillic: "04D5", + aigujarati: "0A90", + aigurmukhi: "0A10", + aimatragurmukhi: "0A48", + ainarabic: "0639", + ainfinalarabic: "FECA", + aininitialarabic: "FECB", + ainmedialarabic: "FECC", + ainvertedbreve: "0203", + aivowelsignbengali: "09C8", + aivowelsigndeva: "0948", + aivowelsigngujarati: "0AC8", + akatakana: "30A2", + akatakanahalfwidth: "FF71", + akorean: "314F", + alef: "05D0", + alefarabic: "0627", + alefdageshhebrew: "FB30", + aleffinalarabic: "FE8E", + alefhamzaabovearabic: "0623", + alefhamzaabovefinalarabic: "FE84", + alefhamzabelowarabic: "0625", + alefhamzabelowfinalarabic: "FE88", + alefhebrew: "05D0", + aleflamedhebrew: "FB4F", + alefmaddaabovearabic: "0622", + alefmaddaabovefinalarabic: "FE82", + alefmaksuraarabic: "0649", + alefmaksurafinalarabic: "FEF0", + alefmaksurainitialarabic: "FEF3", + alefmaksuramedialarabic: "FEF4", + alefpatahhebrew: "FB2E", + alefqamatshebrew: "FB2F", + aleph: "2135", + allequal: "224C", + alpha: "03B1", + alphatonos: "03AC", + amacron: "0101", + amonospace: "FF41", + ampersand: "0026", + ampersandmonospace: "FF06", + ampersandsmall: "F726", + amsquare: "33C2", + anbopomofo: "3122", + angbopomofo: "3124", + angkhankhuthai: "0E5A", + angle: "2220", + anglebracketleft: "3008", + anglebracketleftvertical: "FE3F", + anglebracketright: "3009", + anglebracketrightvertical: "FE40", + angleleft: "2329", + angleright: "232A", + angstrom: "212B", + anoteleia: "0387", + anudattadeva: "0952", + anusvarabengali: "0982", + anusvaradeva: "0902", + anusvaragujarati: "0A82", + aogonek: "0105", + apaatosquare: "3300", + aparen: "249C", + apostrophearmenian: "055A", + apostrophemod: "02BC", + apple: "F8FF", + approaches: "2250", + approxequal: "2248", + approxequalorimage: "2252", + approximatelyequal: "2245", + araeaekorean: "318E", + araeakorean: "318D", + arc: "2312", + arighthalfring: "1E9A", + aring: "00E5", + aringacute: "01FB", + aringbelow: "1E01", + arrowboth: "2194", + arrowdashdown: "21E3", + arrowdashleft: "21E0", + arrowdashright: "21E2", + arrowdashup: "21E1", + arrowdblboth: "21D4", + arrowdbldown: "21D3", + arrowdblleft: "21D0", + arrowdblright: "21D2", + arrowdblup: "21D1", + arrowdown: "2193", + arrowdownleft: "2199", + arrowdownright: "2198", + arrowdownwhite: "21E9", + arrowheaddownmod: "02C5", + arrowheadleftmod: "02C2", + arrowheadrightmod: "02C3", + arrowheadupmod: "02C4", + arrowhorizex: "F8E7", + arrowleft: "2190", + arrowleftdbl: "21D0", + arrowleftdblstroke: "21CD", + arrowleftoverright: "21C6", + arrowleftwhite: "21E6", + arrowright: "2192", + arrowrightdblstroke: "21CF", + arrowrightheavy: "279E", + arrowrightoverleft: "21C4", + arrowrightwhite: "21E8", + arrowtableft: "21E4", + arrowtabright: "21E5", + arrowup: "2191", + arrowupdn: "2195", + arrowupdnbse: "21A8", + arrowupdownbase: "21A8", + arrowupleft: "2196", + arrowupleftofdown: "21C5", + arrowupright: "2197", + arrowupwhite: "21E7", + arrowvertex: "F8E6", + asciicircum: "005E", + asciicircummonospace: "FF3E", + asciitilde: "007E", + asciitildemonospace: "FF5E", + ascript: "0251", + ascriptturned: "0252", + asmallhiragana: "3041", + asmallkatakana: "30A1", + asmallkatakanahalfwidth: "FF67", + asterisk: "002A", + asteriskaltonearabic: "066D", + asteriskarabic: "066D", + asteriskmath: "2217", + asteriskmonospace: "FF0A", + asterisksmall: "FE61", + asterism: "2042", + asuperior: "F6E9", + asymptoticallyequal: "2243", + at: "0040", + atilde: "00E3", + atmonospace: "FF20", + atsmall: "FE6B", + aturned: "0250", + aubengali: "0994", + aubopomofo: "3120", + audeva: "0914", + augujarati: "0A94", + augurmukhi: "0A14", + aulengthmarkbengali: "09D7", + aumatragurmukhi: "0A4C", + auvowelsignbengali: "09CC", + auvowelsigndeva: "094C", + auvowelsigngujarati: "0ACC", + avagrahadeva: "093D", + aybarmenian: "0561", + ayin: "05E2", + ayinaltonehebrew: "FB20", + ayinhebrew: "05E2", + b: "0062", + babengali: "09AC", + backslash: "005C", + backslashmonospace: "FF3C", + badeva: "092C", + bagujarati: "0AAC", + bagurmukhi: "0A2C", + bahiragana: "3070", + bahtthai: "0E3F", + bakatakana: "30D0", + bar: "007C", + barmonospace: "FF5C", + bbopomofo: "3105", + bcircle: "24D1", + bdotaccent: "1E03", + bdotbelow: "1E05", + beamedsixteenthnotes: "266C", + because: "2235", + becyrillic: "0431", + beharabic: "0628", + behfinalarabic: "FE90", + behinitialarabic: "FE91", + behiragana: "3079", + behmedialarabic: "FE92", + behmeeminitialarabic: "FC9F", + behmeemisolatedarabic: "FC08", + behnoonfinalarabic: "FC6D", + bekatakana: "30D9", + benarmenian: "0562", + bet: "05D1", + beta: "03B2", + betasymbolgreek: "03D0", + betdagesh: "FB31", + betdageshhebrew: "FB31", + bethebrew: "05D1", + betrafehebrew: "FB4C", + bhabengali: "09AD", + bhadeva: "092D", + bhagujarati: "0AAD", + bhagurmukhi: "0A2D", + bhook: "0253", + bihiragana: "3073", + bikatakana: "30D3", + bilabialclick: "0298", + bindigurmukhi: "0A02", + birusquare: "3331", + blackcircle: "25CF", + blackdiamond: "25C6", + blackdownpointingtriangle: "25BC", + blackleftpointingpointer: "25C4", + blackleftpointingtriangle: "25C0", + blacklenticularbracketleft: "3010", + blacklenticularbracketleftvertical: "FE3B", + blacklenticularbracketright: "3011", + blacklenticularbracketrightvertical: "FE3C", + blacklowerlefttriangle: "25E3", + blacklowerrighttriangle: "25E2", + blackrectangle: "25AC", + blackrightpointingpointer: "25BA", + blackrightpointingtriangle: "25B6", + blacksmallsquare: "25AA", + blacksmilingface: "263B", + blacksquare: "25A0", + blackstar: "2605", + blackupperlefttriangle: "25E4", + blackupperrighttriangle: "25E5", + blackuppointingsmalltriangle: "25B4", + blackuppointingtriangle: "25B2", + blank: "2423", + blinebelow: "1E07", + block: "2588", + bmonospace: "FF42", + bobaimaithai: "0E1A", + bohiragana: "307C", + bokatakana: "30DC", + bparen: "249D", + bqsquare: "33C3", + braceex: "F8F4", + braceleft: "007B", + braceleftbt: "F8F3", + braceleftmid: "F8F2", + braceleftmonospace: "FF5B", + braceleftsmall: "FE5B", + bracelefttp: "F8F1", + braceleftvertical: "FE37", + braceright: "007D", + bracerightbt: "F8FE", + bracerightmid: "F8FD", + bracerightmonospace: "FF5D", + bracerightsmall: "FE5C", + bracerighttp: "F8FC", + bracerightvertical: "FE38", + bracketleft: "005B", + bracketleftbt: "F8F0", + bracketleftex: "F8EF", + bracketleftmonospace: "FF3B", + bracketlefttp: "F8EE", + bracketright: "005D", + bracketrightbt: "F8FB", + bracketrightex: "F8FA", + bracketrightmonospace: "FF3D", + bracketrighttp: "F8F9", + breve: "02D8", + brevebelowcmb: "032E", + brevecmb: "0306", + breveinvertedbelowcmb: "032F", + breveinvertedcmb: "0311", + breveinverteddoublecmb: "0361", + bridgebelowcmb: "032A", + bridgeinvertedbelowcmb: "033A", + brokenbar: "00A6", + bstroke: "0180", + bsuperior: "F6EA", + btopbar: "0183", + buhiragana: "3076", + bukatakana: "30D6", + bullet: "2022", + bulletinverse: "25D8", + bulletoperator: "2219", + bullseye: "25CE", + c: "0063", + caarmenian: "056E", + cabengali: "099A", + cacute: "0107", + cadeva: "091A", + cagujarati: "0A9A", + cagurmukhi: "0A1A", + calsquare: "3388", + candrabindubengali: "0981", + candrabinducmb: "0310", + candrabindudeva: "0901", + candrabindugujarati: "0A81", + capslock: "21EA", + careof: "2105", + caron: "02C7", + caronbelowcmb: "032C", + caroncmb: "030C", + carriagereturn: "21B5", + cbopomofo: "3118", + ccaron: "010D", + ccedilla: "00E7", + ccedillaacute: "1E09", + ccircle: "24D2", + ccircumflex: "0109", + ccurl: "0255", + cdot: "010B", + cdotaccent: "010B", + cdsquare: "33C5", + cedilla: "00B8", + cedillacmb: "0327", + cent: "00A2", + centigrade: "2103", + centinferior: "F6DF", + centmonospace: "FFE0", + centoldstyle: "F7A2", + centsuperior: "F6E0", + chaarmenian: "0579", + chabengali: "099B", + chadeva: "091B", + chagujarati: "0A9B", + chagurmukhi: "0A1B", + chbopomofo: "3114", + cheabkhasiancyrillic: "04BD", + checkmark: "2713", + checyrillic: "0447", + chedescenderabkhasiancyrillic: "04BF", + chedescendercyrillic: "04B7", + chedieresiscyrillic: "04F5", + cheharmenian: "0573", + chekhakassiancyrillic: "04CC", + cheverticalstrokecyrillic: "04B9", + chi: "03C7", + chieuchacirclekorean: "3277", + chieuchaparenkorean: "3217", + chieuchcirclekorean: "3269", + chieuchkorean: "314A", + chieuchparenkorean: "3209", + chochangthai: "0E0A", + chochanthai: "0E08", + chochingthai: "0E09", + chochoethai: "0E0C", + chook: "0188", + cieucacirclekorean: "3276", + cieucaparenkorean: "3216", + cieuccirclekorean: "3268", + cieuckorean: "3148", + cieucparenkorean: "3208", + cieucuparenkorean: "321C", + circle: "25CB", + circlemultiply: "2297", + circleot: "2299", + circleplus: "2295", + circlepostalmark: "3036", + circlewithlefthalfblack: "25D0", + circlewithrighthalfblack: "25D1", + circumflex: "02C6", + circumflexbelowcmb: "032D", + circumflexcmb: "0302", + clear: "2327", + clickalveolar: "01C2", + clickdental: "01C0", + clicklateral: "01C1", + clickretroflex: "01C3", + club: "2663", + clubsuitblack: "2663", + clubsuitwhite: "2667", + cmcubedsquare: "33A4", + cmonospace: "FF43", + cmsquaredsquare: "33A0", + coarmenian: "0581", + colon: "003A", + colonmonetary: "20A1", + colonmonospace: "FF1A", + colonsign: "20A1", + colonsmall: "FE55", + colontriangularhalfmod: "02D1", + colontriangularmod: "02D0", + comma: "002C", + commaabovecmb: "0313", + commaaboverightcmb: "0315", + commaaccent: "F6C3", + commaarabic: "060C", + commaarmenian: "055D", + commainferior: "F6E1", + commamonospace: "FF0C", + commareversedabovecmb: "0314", + commareversedmod: "02BD", + commasmall: "FE50", + commasuperior: "F6E2", + commaturnedabovecmb: "0312", + commaturnedmod: "02BB", + compass: "263C", + congruent: "2245", + contourintegral: "222E", + control: "2303", + controlACK: "0006", + controlBEL: "0007", + controlBS: "0008", + controlCAN: "0018", + controlCR: "000D", + controlDC1: "0011", + controlDC2: "0012", + controlDC3: "0013", + controlDC4: "0014", + controlDEL: "007F", + controlDLE: "0010", + controlEM: "0019", + controlENQ: "0005", + controlEOT: "0004", + controlESC: "001B", + controlETB: "0017", + controlETX: "0003", + controlFF: "000C", + controlFS: "001C", + controlGS: "001D", + controlHT: "0009", + controlLF: "000A", + controlNAK: "0015", + controlRS: "001E", + controlSI: "000F", + controlSO: "000E", + controlSOT: "0002", + controlSTX: "0001", + controlSUB: "001A", + controlSYN: "0016", + controlUS: "001F", + controlVT: "000B", + copyright: "00A9", + copyrightsans: "F8E9", + copyrightserif: "F6D9", + cornerbracketleft: "300C", + cornerbracketlefthalfwidth: "FF62", + cornerbracketleftvertical: "FE41", + cornerbracketright: "300D", + cornerbracketrighthalfwidth: "FF63", + cornerbracketrightvertical: "FE42", + corporationsquare: "337F", + cosquare: "33C7", + coverkgsquare: "33C6", + cparen: "249E", + cruzeiro: "20A2", + cstretched: "0297", + curlyand: "22CF", + curlyor: "22CE", + currency: "00A4", + cyrBreve: "F6D1", + cyrFlex: "F6D2", + cyrbreve: "F6D4", + cyrflex: "F6D5", + d: "0064", + daarmenian: "0564", + dabengali: "09A6", + dadarabic: "0636", + dadeva: "0926", + dadfinalarabic: "FEBE", + dadinitialarabic: "FEBF", + dadmedialarabic: "FEC0", + dagesh: "05BC", + dageshhebrew: "05BC", + dagger: "2020", + daggerdbl: "2021", + dagujarati: "0AA6", + dagurmukhi: "0A26", + dahiragana: "3060", + dakatakana: "30C0", + dalarabic: "062F", + dalet: "05D3", + daletdagesh: "FB33", + daletdageshhebrew: "FB33", + dalethatafpatah: "05D3 05B2", + dalethatafpatahhebrew: "05D3 05B2", + dalethatafsegol: "05D3 05B1", + dalethatafsegolhebrew: "05D3 05B1", + dalethebrew: "05D3", + 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: "FEAA", + dammaarabic: "064F", + dammalowarabic: "064F", + dammatanaltonearabic: "064C", + dammatanarabic: "064C", + danda: "0964", + dargahebrew: "05A7", + dargalefthebrew: "05A7", + dasiapneumatacyrilliccmb: "0485", + dblGrave: "F6D3", + dblanglebracketleft: "300A", + dblanglebracketleftvertical: "FE3D", + dblanglebracketright: "300B", + dblanglebracketrightvertical: "FE3E", + dblarchinvertedbelowcmb: "032B", + dblarrowleft: "21D4", + dblarrowright: "21D2", + dbldanda: "0965", + dblgrave: "F6D6", + dblgravecmb: "030F", + dblintegral: "222C", + dbllowline: "2017", + dbllowlinecmb: "0333", + dbloverlinecmb: "033F", + dblprimemod: "02BA", + dblverticalbar: "2016", + dblverticallineabovecmb: "030E", + dbopomofo: "3109", + dbsquare: "33C8", + dcaron: "010F", + dcedilla: "1E11", + dcircle: "24D3", + dcircumflexbelow: "1E13", + dcroat: "0111", + ddabengali: "09A1", + ddadeva: "0921", + ddagujarati: "0AA1", + ddagurmukhi: "0A21", + ddalarabic: "0688", + ddalfinalarabic: "FB89", + dddhadeva: "095C", + ddhabengali: "09A2", + ddhadeva: "0922", + ddhagujarati: "0AA2", + ddhagurmukhi: "0A22", + ddotaccent: "1E0B", + ddotbelow: "1E0D", + decimalseparatorarabic: "066B", + decimalseparatorpersian: "066B", + decyrillic: "0434", + degree: "00B0", + dehihebrew: "05AD", + dehiragana: "3067", + deicoptic: "03EF", + dekatakana: "30C7", + deleteleft: "232B", + deleteright: "2326", + delta: "03B4", + deltaturned: "018D", + denominatorminusonenumeratorbengali: "09F8", + dezh: "02A4", + dhabengali: "09A7", + dhadeva: "0927", + dhagujarati: "0AA7", + dhagurmukhi: "0A27", + dhook: "0257", + dialytikatonos: "0385", + dialytikatonoscmb: "0344", + diamond: "2666", + diamondsuitwhite: "2662", + dieresis: "00A8", + dieresisacute: "F6D7", + dieresisbelowcmb: "0324", + dieresiscmb: "0308", + dieresisgrave: "F6D8", + dieresistonos: "0385", + dihiragana: "3062", + dikatakana: "30C2", + dittomark: "3003", + divide: "00F7", + divides: "2223", + divisionslash: "2215", + djecyrillic: "0452", + dkshade: "2593", + dlinebelow: "1E0F", + dlsquare: "3397", + dmacron: "0111", + dmonospace: "FF44", + dnblock: "2584", + dochadathai: "0E0E", + dodekthai: "0E14", + dohiragana: "3069", + dokatakana: "30C9", + dollar: "0024", + dollarinferior: "F6E3", + dollarmonospace: "FF04", + dollaroldstyle: "F724", + dollarsmall: "FE69", + dollarsuperior: "F6E4", + dong: "20AB", + dorusquare: "3326", + dotaccent: "02D9", + dotaccentcmb: "0307", + dotbelowcmb: "0323", + dotbelowcomb: "0323", + dotkatakana: "30FB", + dotlessi: "0131", + dotlessj: "F6BE", + dotlessjstrokehook: "0284", + dotmath: "22C5", + dottedcircle: "25CC", + doubleyodpatah: "FB1F", + doubleyodpatahhebrew: "FB1F", + downtackbelowcmb: "031E", + downtackmod: "02D5", + dparen: "249F", + dsuperior: "F6EB", + dtail: "0256", + dtopbar: "018C", + duhiragana: "3065", + dukatakana: "30C5", + dz: "01F3", + dzaltone: "02A3", + dzcaron: "01C6", + dzcurl: "02A5", + dzeabkhasiancyrillic: "04E1", + dzecyrillic: "0455", + dzhecyrillic: "045F", + e: "0065", + eacute: "00E9", + earth: "2641", + ebengali: "098F", + ebopomofo: "311C", + ebreve: "0115", + ecandradeva: "090D", + ecandragujarati: "0A8D", + ecandravowelsigndeva: "0945", + ecandravowelsigngujarati: "0AC5", + ecaron: "011B", + ecedillabreve: "1E1D", + echarmenian: "0565", + echyiwnarmenian: "0587", + ecircle: "24D4", + ecircumflex: "00EA", + ecircumflexacute: "1EBF", + ecircumflexbelow: "1E19", + ecircumflexdotbelow: "1EC7", + ecircumflexgrave: "1EC1", + ecircumflexhookabove: "1EC3", + ecircumflextilde: "1EC5", + ecyrillic: "0454", + edblgrave: "0205", + edeva: "090F", + edieresis: "00EB", + edot: "0117", + edotaccent: "0117", + edotbelow: "1EB9", + eegurmukhi: "0A0F", + eematragurmukhi: "0A47", + efcyrillic: "0444", + egrave: "00E8", + egujarati: "0A8F", + eharmenian: "0567", + ehbopomofo: "311D", + ehiragana: "3048", + ehookabove: "1EBB", + eibopomofo: "311F", + eight: "0038", + eightarabic: "0668", + eightbengali: "09EE", + eightcircle: "2467", + eightcircleinversesansserif: "2791", + eightdeva: "096E", + eighteencircle: "2471", + eighteenparen: "2485", + eighteenperiod: "2499", + eightgujarati: "0AEE", + eightgurmukhi: "0A6E", + eighthackarabic: "0668", + eighthangzhou: "3028", + eighthnotebeamed: "266B", + eightideographicparen: "3227", + eightinferior: "2088", + eightmonospace: "FF18", + eightoldstyle: "F738", + eightparen: "247B", + eightperiod: "248F", + eightpersian: "06F8", + eightroman: "2177", + eightsuperior: "2078", + eightthai: "0E58", + einvertedbreve: "0207", + eiotifiedcyrillic: "0465", + ekatakana: "30A8", + ekatakanahalfwidth: "FF74", + ekonkargurmukhi: "0A74", + ekorean: "3154", + elcyrillic: "043B", + element: "2208", + elevencircle: "246A", + elevenparen: "247E", + elevenperiod: "2492", + elevenroman: "217A", + ellipsis: "2026", + ellipsisvertical: "22EE", + emacron: "0113", + emacronacute: "1E17", + emacrongrave: "1E15", + emcyrillic: "043C", + emdash: "2014", + emdashvertical: "FE31", + emonospace: "FF45", + emphasismarkarmenian: "055B", + emptyset: "2205", + enbopomofo: "3123", + encyrillic: "043D", + endash: "2013", + endashvertical: "FE32", + endescendercyrillic: "04A3", + eng: "014B", + engbopomofo: "3125", + enghecyrillic: "04A5", + enhookcyrillic: "04C8", + enspace: "2002", + eogonek: "0119", + eokorean: "3153", + eopen: "025B", + eopenclosed: "029A", + eopenreversed: "025C", + eopenreversedclosed: "025E", + eopenreversedhook: "025D", + eparen: "24A0", + epsilon: "03B5", + epsilontonos: "03AD", + equal: "003D", + equalmonospace: "FF1D", + equalsmall: "FE66", + equalsuperior: "207C", + equivalence: "2261", + erbopomofo: "3126", + ercyrillic: "0440", + ereversed: "0258", + ereversedcyrillic: "044D", + escyrillic: "0441", + esdescendercyrillic: "04AB", + esh: "0283", + eshcurl: "0286", + eshortdeva: "090E", + eshortvowelsigndeva: "0946", + eshreversedloop: "01AA", + eshsquatreversed: "0285", + esmallhiragana: "3047", + esmallkatakana: "30A7", + esmallkatakanahalfwidth: "FF6A", + estimated: "212E", + esuperior: "F6EC", + eta: "03B7", + etarmenian: "0568", + etatonos: "03AE", + eth: "00F0", + etilde: "1EBD", + etildebelow: "1E1B", + etnahtafoukhhebrew: "0591", + etnahtafoukhlefthebrew: "0591", + etnahtahebrew: "0591", + etnahtalefthebrew: "0591", + eturned: "01DD", + eukorean: "3161", + euro: "20AC", + evowelsignbengali: "09C7", + evowelsigndeva: "0947", + evowelsigngujarati: "0AC7", + exclam: "0021", + exclamarmenian: "055C", + exclamdbl: "203C", + exclamdown: "00A1", + exclamdownsmall: "F7A1", + exclammonospace: "FF01", + exclamsmall: "F721", + existential: "2203", + ezh: "0292", + ezhcaron: "01EF", + ezhcurl: "0293", + ezhreversed: "01B9", + ezhtail: "01BA", + f: "0066", + fadeva: "095E", + fagurmukhi: "0A5E", + fahrenheit: "2109", + fathaarabic: "064E", + fathalowarabic: "064E", + fathatanarabic: "064B", + fbopomofo: "3108", + fcircle: "24D5", + fdotaccent: "1E1F", + feharabic: "0641", + feharmenian: "0586", + fehfinalarabic: "FED2", + fehinitialarabic: "FED3", + fehmedialarabic: "FED4", + feicoptic: "03E5", + female: "2640", + ff: "FB00", + ffi: "FB03", + ffl: "FB04", + fi: "FB01", + fifteencircle: "246E", + fifteenparen: "2482", + fifteenperiod: "2496", + figuredash: "2012", + filledbox: "25A0", + filledrect: "25AC", + finalkaf: "05DA", + finalkafdagesh: "FB3A", + finalkafdageshhebrew: "FB3A", + finalkafhebrew: "05DA", + finalkafqamats: "05DA 05B8", + finalkafqamatshebrew: "05DA 05B8", + finalkafsheva: "05DA 05B0", + finalkafshevahebrew: "05DA 05B0", + finalmem: "05DD", + finalmemhebrew: "05DD", + finalnun: "05DF", + finalnunhebrew: "05DF", + finalpe: "05E3", + finalpehebrew: "05E3", + finaltsadi: "05E5", + finaltsadihebrew: "05E5", + firsttonechinese: "02C9", + fisheye: "25C9", + fitacyrillic: "0473", + five: "0035", + fivearabic: "0665", + fivebengali: "09EB", + fivecircle: "2464", + fivecircleinversesansserif: "278E", + fivedeva: "096B", + fiveeighths: "215D", + fivegujarati: "0AEB", + fivegurmukhi: "0A6B", + fivehackarabic: "0665", + fivehangzhou: "3025", + fiveideographicparen: "3224", + fiveinferior: "2085", + fivemonospace: "FF15", + fiveoldstyle: "F735", + fiveparen: "2478", + fiveperiod: "248C", + fivepersian: "06F5", + fiveroman: "2174", + fivesuperior: "2075", + fivethai: "0E55", + fl: "FB02", + florin: "0192", + fmonospace: "FF46", + fmsquare: "3399", + fofanthai: "0E1F", + fofathai: "0E1D", + fongmanthai: "0E4F", + forall: "2200", + four: "0034", + fourarabic: "0664", + fourbengali: "09EA", + fourcircle: "2463", + fourcircleinversesansserif: "278D", + fourdeva: "096A", + fourgujarati: "0AEA", + fourgurmukhi: "0A6A", + fourhackarabic: "0664", + fourhangzhou: "3024", + fourideographicparen: "3223", + fourinferior: "2084", + fourmonospace: "FF14", + fournumeratorbengali: "09F7", + fouroldstyle: "F734", + fourparen: "2477", + fourperiod: "248B", + fourpersian: "06F4", + fourroman: "2173", + foursuperior: "2074", + fourteencircle: "246D", + fourteenparen: "2481", + fourteenperiod: "2495", + fourthai: "0E54", + fourthtonechinese: "02CB", + fparen: "24A1", + fraction: "2044", + franc: "20A3", + g: "0067", + gabengali: "0997", + gacute: "01F5", + gadeva: "0917", + gafarabic: "06AF", + gaffinalarabic: "FB93", + gafinitialarabic: "FB94", + gafmedialarabic: "FB95", + gagujarati: "0A97", + gagurmukhi: "0A17", + gahiragana: "304C", + gakatakana: "30AC", + gamma: "03B3", + gammalatinsmall: "0263", + gammasuperior: "02E0", + gangiacoptic: "03EB", + gbopomofo: "310D", + gbreve: "011F", + gcaron: "01E7", + gcedilla: "0123", + gcircle: "24D6", + gcircumflex: "011D", + gcommaaccent: "0123", + gdot: "0121", + gdotaccent: "0121", + gecyrillic: "0433", + gehiragana: "3052", + gekatakana: "30B2", + geometricallyequal: "2251", + gereshaccenthebrew: "059C", + gereshhebrew: "05F3", + gereshmuqdamhebrew: "059D", + germandbls: "00DF", + gershayimaccenthebrew: "059E", + gershayimhebrew: "05F4", + getamark: "3013", + ghabengali: "0998", + ghadarmenian: "0572", + ghadeva: "0918", + ghagujarati: "0A98", + ghagurmukhi: "0A18", + ghainarabic: "063A", + ghainfinalarabic: "FECE", + ghaininitialarabic: "FECF", + ghainmedialarabic: "FED0", + ghemiddlehookcyrillic: "0495", + ghestrokecyrillic: "0493", + gheupturncyrillic: "0491", + ghhadeva: "095A", + ghhagurmukhi: "0A5A", + ghook: "0260", + ghzsquare: "3393", + gihiragana: "304E", + gikatakana: "30AE", + gimarmenian: "0563", + gimel: "05D2", + gimeldagesh: "FB32", + gimeldageshhebrew: "FB32", + gimelhebrew: "05D2", + gjecyrillic: "0453", + glottalinvertedstroke: "01BE", + glottalstop: "0294", + glottalstopinverted: "0296", + glottalstopmod: "02C0", + glottalstopreversed: "0295", + glottalstopreversedmod: "02C1", + glottalstopreversedsuperior: "02E4", + glottalstopstroke: "02A1", + glottalstopstrokereversed: "02A2", + gmacron: "1E21", + gmonospace: "FF47", + gohiragana: "3054", + gokatakana: "30B4", + gparen: "24A2", + gpasquare: "33AC", + gradient: "2207", + grave: "0060", + gravebelowcmb: "0316", + gravecmb: "0300", + gravecomb: "0300", + gravedeva: "0953", + gravelowmod: "02CE", + gravemonospace: "FF40", + gravetonecmb: "0340", + greater: "003E", + greaterequal: "2265", + greaterequalorless: "22DB", + greatermonospace: "FF1E", + greaterorequivalent: "2273", + greaterorless: "2277", + greateroverequal: "2267", + greatersmall: "FE65", + gscript: "0261", + gstroke: "01E5", + guhiragana: "3050", + guillemotleft: "00AB", + guillemotright: "00BB", + guilsinglleft: "2039", + guilsinglright: "203A", + gukatakana: "30B0", + guramusquare: "3318", + gysquare: "33C9", + h: "0068", + haabkhasiancyrillic: "04A9", + haaltonearabic: "06C1", + habengali: "09B9", + hadescendercyrillic: "04B3", + hadeva: "0939", + hagujarati: "0AB9", + hagurmukhi: "0A39", + haharabic: "062D", + hahfinalarabic: "FEA2", + hahinitialarabic: "FEA3", + hahiragana: "306F", + hahmedialarabic: "FEA4", + haitusquare: "332A", + hakatakana: "30CF", + hakatakanahalfwidth: "FF8A", + halantgurmukhi: "0A4D", + hamzaarabic: "0621", + hamzadammaarabic: "0621 064F", + hamzadammatanarabic: "0621 064C", + hamzafathaarabic: "0621 064E", + hamzafathatanarabic: "0621 064B", + hamzalowarabic: "0621", + hamzalowkasraarabic: "0621 0650", + hamzalowkasratanarabic: "0621 064D", + hamzasukunarabic: "0621 0652", + hangulfiller: "3164", + hardsigncyrillic: "044A", + harpoonleftbarbup: "21BC", + harpoonrightbarbup: "21C0", + hasquare: "33CA", + hatafpatah: "05B2", + hatafpatah16: "05B2", + hatafpatah23: "05B2", + hatafpatah2f: "05B2", + hatafpatahhebrew: "05B2", + hatafpatahnarrowhebrew: "05B2", + hatafpatahquarterhebrew: "05B2", + hatafpatahwidehebrew: "05B2", + hatafqamats: "05B3", + hatafqamats1b: "05B3", + hatafqamats28: "05B3", + hatafqamats34: "05B3", + hatafqamatshebrew: "05B3", + hatafqamatsnarrowhebrew: "05B3", + hatafqamatsquarterhebrew: "05B3", + hatafqamatswidehebrew: "05B3", + hatafsegol: "05B1", + hatafsegol17: "05B1", + hatafsegol24: "05B1", + hatafsegol30: "05B1", + hatafsegolhebrew: "05B1", + hatafsegolnarrowhebrew: "05B1", + hatafsegolquarterhebrew: "05B1", + hatafsegolwidehebrew: "05B1", + hbar: "0127", + hbopomofo: "310F", + hbrevebelow: "1E2B", + hcedilla: "1E29", + hcircle: "24D7", + hcircumflex: "0125", + hdieresis: "1E27", + hdotaccent: "1E23", + hdotbelow: "1E25", + he: "05D4", + heart: "2665", + heartsuitblack: "2665", + heartsuitwhite: "2661", + hedagesh: "FB34", + hedageshhebrew: "FB34", + hehaltonearabic: "06C1", + heharabic: "0647", + hehebrew: "05D4", + hehfinalaltonearabic: "FBA7", + hehfinalalttwoarabic: "FEEA", + hehfinalarabic: "FEEA", + hehhamzaabovefinalarabic: "FBA5", + hehhamzaaboveisolatedarabic: "FBA4", + hehinitialaltonearabic: "FBA8", + hehinitialarabic: "FEEB", + hehiragana: "3078", + hehmedialaltonearabic: "FBA9", + hehmedialarabic: "FEEC", + heiseierasquare: "337B", + hekatakana: "30D8", + hekatakanahalfwidth: "FF8D", + hekutaarusquare: "3336", + henghook: "0267", + herutusquare: "3339", + het: "05D7", + hethebrew: "05D7", + hhook: "0266", + hhooksuperior: "02B1", + hieuhacirclekorean: "327B", + hieuhaparenkorean: "321B", + hieuhcirclekorean: "326D", + hieuhkorean: "314E", + hieuhparenkorean: "320D", + hihiragana: "3072", + hikatakana: "30D2", + hikatakanahalfwidth: "FF8B", + hiriq: "05B4", + hiriq14: "05B4", + hiriq21: "05B4", + hiriq2d: "05B4", + hiriqhebrew: "05B4", + hiriqnarrowhebrew: "05B4", + hiriqquarterhebrew: "05B4", + hiriqwidehebrew: "05B4", + hlinebelow: "1E96", + hmonospace: "FF48", + hoarmenian: "0570", + hohipthai: "0E2B", + hohiragana: "307B", + hokatakana: "30DB", + hokatakanahalfwidth: "FF8E", + holam: "05B9", + holam19: "05B9", + holam26: "05B9", + holam32: "05B9", + holamhebrew: "05B9", + holamnarrowhebrew: "05B9", + holamquarterhebrew: "05B9", + holamwidehebrew: "05B9", + honokhukthai: "0E2E", + hookabovecomb: "0309", + hookcmb: "0309", + hookpalatalizedbelowcmb: "0321", + hookretroflexbelowcmb: "0322", + hoonsquare: "3342", + horicoptic: "03E9", + horizontalbar: "2015", + horncmb: "031B", + hotsprings: "2668", + house: "2302", + hparen: "24A3", + hsuperior: "02B0", + hturned: "0265", + huhiragana: "3075", + huiitosquare: "3333", + hukatakana: "30D5", + hukatakanahalfwidth: "FF8C", + hungarumlaut: "02DD", + hungarumlautcmb: "030B", + hv: "0195", + hyphen: "002D", + hypheninferior: "F6E5", + hyphenmonospace: "FF0D", + hyphensmall: "FE63", + hyphensuperior: "F6E6", + hyphentwo: "2010", + i: "0069", + iacute: "00ED", + iacyrillic: "044F", + ibengali: "0987", + ibopomofo: "3127", + ibreve: "012D", + icaron: "01D0", + icircle: "24D8", + icircumflex: "00EE", + icyrillic: "0456", + idblgrave: "0209", + ideographearthcircle: "328F", + ideographfirecircle: "328B", + ideographicallianceparen: "323F", + ideographiccallparen: "323A", + ideographiccentrecircle: "32A5", + ideographicclose: "3006", + ideographiccomma: "3001", + ideographiccommaleft: "FF64", + ideographiccongratulationparen: "3237", + ideographiccorrectcircle: "32A3", + ideographicearthparen: "322F", + ideographicenterpriseparen: "323D", + ideographicexcellentcircle: "329D", + ideographicfestivalparen: "3240", + ideographicfinancialcircle: "3296", + ideographicfinancialparen: "3236", + ideographicfireparen: "322B", + ideographichaveparen: "3232", + ideographichighcircle: "32A4", + ideographiciterationmark: "3005", + ideographiclaborcircle: "3298", + ideographiclaborparen: "3238", + ideographicleftcircle: "32A7", + ideographiclowcircle: "32A6", + ideographicmedicinecircle: "32A9", + ideographicmetalparen: "322E", + ideographicmoonparen: "322A", + ideographicnameparen: "3234", + ideographicperiod: "3002", + ideographicprintcircle: "329E", + ideographicreachparen: "3243", + ideographicrepresentparen: "3239", + ideographicresourceparen: "323E", + ideographicrightcircle: "32A8", + ideographicsecretcircle: "3299", + ideographicselfparen: "3242", + ideographicsocietyparen: "3233", + ideographicspace: "3000", + ideographicspecialparen: "3235", + ideographicstockparen: "3231", + ideographicstudyparen: "323B", + ideographicsunparen: "3230", + ideographicsuperviseparen: "323C", + ideographicwaterparen: "322C", + ideographicwoodparen: "322D", + ideographiczero: "3007", + ideographmetalcircle: "328E", + ideographmooncircle: "328A", + ideographnamecircle: "3294", + ideographsuncircle: "3290", + ideographwatercircle: "328C", + ideographwoodcircle: "328D", + ideva: "0907", + idieresis: "00EF", + idieresisacute: "1E2F", + idieresiscyrillic: "04E5", + idotbelow: "1ECB", + iebrevecyrillic: "04D7", + iecyrillic: "0435", + ieungacirclekorean: "3275", + ieungaparenkorean: "3215", + ieungcirclekorean: "3267", + ieungkorean: "3147", + ieungparenkorean: "3207", + igrave: "00EC", + igujarati: "0A87", + igurmukhi: "0A07", + ihiragana: "3044", + ihookabove: "1EC9", + iibengali: "0988", + iicyrillic: "0438", + iideva: "0908", + iigujarati: "0A88", + iigurmukhi: "0A08", + iimatragurmukhi: "0A40", + iinvertedbreve: "020B", + iishortcyrillic: "0439", + iivowelsignbengali: "09C0", + iivowelsigndeva: "0940", + iivowelsigngujarati: "0AC0", + ij: "0133", + ikatakana: "30A4", + ikatakanahalfwidth: "FF72", + ikorean: "3163", + ilde: "02DC", + iluyhebrew: "05AC", + imacron: "012B", + imacroncyrillic: "04E3", + imageorapproximatelyequal: "2253", + imatragurmukhi: "0A3F", + imonospace: "FF49", + increment: "2206", + infinity: "221E", + iniarmenian: "056B", + integral: "222B", + integralbottom: "2321", + integralbt: "2321", + integralex: "F8F5", + integraltop: "2320", + integraltp: "2320", + intersection: "2229", + intisquare: "3305", + invbullet: "25D8", + invcircle: "25D9", + invsmileface: "263B", + iocyrillic: "0451", + iogonek: "012F", + iota: "03B9", + iotadieresis: "03CA", + iotadieresistonos: "0390", + iotalatin: "0269", + iotatonos: "03AF", + iparen: "24A4", + irigurmukhi: "0A72", + ismallhiragana: "3043", + ismallkatakana: "30A3", + ismallkatakanahalfwidth: "FF68", + issharbengali: "09FA", + istroke: "0268", + isuperior: "F6ED", + iterationhiragana: "309D", + iterationkatakana: "30FD", + itilde: "0129", + itildebelow: "1E2D", + iubopomofo: "3129", + iucyrillic: "044E", + ivowelsignbengali: "09BF", + ivowelsigndeva: "093F", + ivowelsigngujarati: "0ABF", + izhitsacyrillic: "0475", + izhitsadblgravecyrillic: "0477", + j: "006A", + jaarmenian: "0571", + jabengali: "099C", + jadeva: "091C", + jagujarati: "0A9C", + jagurmukhi: "0A1C", + jbopomofo: "3110", + jcaron: "01F0", + jcircle: "24D9", + jcircumflex: "0135", + jcrossedtail: "029D", + jdotlessstroke: "025F", + jecyrillic: "0458", + jeemarabic: "062C", + jeemfinalarabic: "FE9E", + jeeminitialarabic: "FE9F", + jeemmedialarabic: "FEA0", + jeharabic: "0698", + jehfinalarabic: "FB8B", + jhabengali: "099D", + jhadeva: "091D", + jhagujarati: "0A9D", + jhagurmukhi: "0A1D", + jheharmenian: "057B", + jis: "3004", + jmonospace: "FF4A", + jparen: "24A5", + jsuperior: "02B2", + k: "006B", + kabashkircyrillic: "04A1", + kabengali: "0995", + kacute: "1E31", + kacyrillic: "043A", + kadescendercyrillic: "049B", + kadeva: "0915", + kaf: "05DB", + kafarabic: "0643", + kafdagesh: "FB3B", + kafdageshhebrew: "FB3B", + kaffinalarabic: "FEDA", + kafhebrew: "05DB", + kafinitialarabic: "FEDB", + kafmedialarabic: "FEDC", + kafrafehebrew: "FB4D", + kagujarati: "0A95", + kagurmukhi: "0A15", + kahiragana: "304B", + kahookcyrillic: "04C4", + kakatakana: "30AB", + kakatakanahalfwidth: "FF76", + kappa: "03BA", + kappasymbolgreek: "03F0", + kapyeounmieumkorean: "3171", + kapyeounphieuphkorean: "3184", + kapyeounpieupkorean: "3178", + kapyeounssangpieupkorean: "3179", + karoriisquare: "330D", + kashidaautoarabic: "0640", + kashidaautonosidebearingarabic: "0640", + kasmallkatakana: "30F5", + kasquare: "3384", + kasraarabic: "0650", + kasratanarabic: "064D", + kastrokecyrillic: "049F", + katahiraprolongmarkhalfwidth: "FF70", + kaverticalstrokecyrillic: "049D", + kbopomofo: "310E", + kcalsquare: "3389", + kcaron: "01E9", + kcedilla: "0137", + kcircle: "24DA", + kcommaaccent: "0137", + kdotbelow: "1E33", + keharmenian: "0584", + kehiragana: "3051", + kekatakana: "30B1", + kekatakanahalfwidth: "FF79", + kenarmenian: "056F", + kesmallkatakana: "30F6", + kgreenlandic: "0138", + khabengali: "0996", + khacyrillic: "0445", + khadeva: "0916", + khagujarati: "0A96", + khagurmukhi: "0A16", + khaharabic: "062E", + khahfinalarabic: "FEA6", + khahinitialarabic: "FEA7", + khahmedialarabic: "FEA8", + kheicoptic: "03E7", + khhadeva: "0959", + khhagurmukhi: "0A59", + khieukhacirclekorean: "3278", + khieukhaparenkorean: "3218", + khieukhcirclekorean: "326A", + khieukhkorean: "314B", + khieukhparenkorean: "320A", + khokhaithai: "0E02", + khokhonthai: "0E05", + khokhuatthai: "0E03", + khokhwaithai: "0E04", + khomutthai: "0E5B", + khook: "0199", + khorakhangthai: "0E06", + khzsquare: "3391", + kihiragana: "304D", + kikatakana: "30AD", + kikatakanahalfwidth: "FF77", + kiroguramusquare: "3315", + kiromeetorusquare: "3316", + kirosquare: "3314", + kiyeokacirclekorean: "326E", + kiyeokaparenkorean: "320E", + kiyeokcirclekorean: "3260", + kiyeokkorean: "3131", + kiyeokparenkorean: "3200", + kiyeoksioskorean: "3133", + kjecyrillic: "045C", + klinebelow: "1E35", + klsquare: "3398", + kmcubedsquare: "33A6", + kmonospace: "FF4B", + kmsquaredsquare: "33A2", + kohiragana: "3053", + kohmsquare: "33C0", + kokaithai: "0E01", + kokatakana: "30B3", + kokatakanahalfwidth: "FF7A", + kooposquare: "331E", + koppacyrillic: "0481", + koreanstandardsymbol: "327F", + koroniscmb: "0343", + kparen: "24A6", + kpasquare: "33AA", + ksicyrillic: "046F", + ktsquare: "33CF", + kturned: "029E", + kuhiragana: "304F", + kukatakana: "30AF", + kukatakanahalfwidth: "FF78", + kvsquare: "33B8", + kwsquare: "33BE", + l: "006C", + labengali: "09B2", + lacute: "013A", + ladeva: "0932", + lagujarati: "0AB2", + lagurmukhi: "0A32", + lakkhangyaothai: "0E45", + lamaleffinalarabic: "FEFC", + lamalefhamzaabovefinalarabic: "FEF8", + lamalefhamzaaboveisolatedarabic: "FEF7", + lamalefhamzabelowfinalarabic: "FEFA", + lamalefhamzabelowisolatedarabic: "FEF9", + lamalefisolatedarabic: "FEFB", + lamalefmaddaabovefinalarabic: "FEF6", + lamalefmaddaaboveisolatedarabic: "FEF5", + lamarabic: "0644", + lambda: "03BB", + lambdastroke: "019B", + lamed: "05DC", + lameddagesh: "FB3C", + lameddageshhebrew: "FB3C", + lamedhebrew: "05DC", + lamedholam: "05DC 05B9", + lamedholamdagesh: "05DC 05B9 05BC", + lamedholamdageshhebrew: "05DC 05B9 05BC", + lamedholamhebrew: "05DC 05B9", + lamfinalarabic: "FEDE", + lamhahinitialarabic: "FCCA", + laminitialarabic: "FEDF", + lamjeeminitialarabic: "FCC9", + lamkhahinitialarabic: "FCCB", + lamlamhehisolatedarabic: "FDF2", + lammedialarabic: "FEE0", + lammeemhahinitialarabic: "FD88", + lammeeminitialarabic: "FCCC", + lammeemjeeminitialarabic: "FEDF FEE4 FEA0", + lammeemkhahinitialarabic: "FEDF FEE4 FEA8", + largecircle: "25EF", + lbar: "019A", + lbelt: "026C", + lbopomofo: "310C", + lcaron: "013E", + lcedilla: "013C", + lcircle: "24DB", + lcircumflexbelow: "1E3D", + lcommaaccent: "013C", + ldot: "0140", + ldotaccent: "0140", + ldotbelow: "1E37", + ldotbelowmacron: "1E39", + leftangleabovecmb: "031A", + lefttackbelowcmb: "0318", + less: "003C", + lessequal: "2264", + lessequalorgreater: "22DA", + lessmonospace: "FF1C", + lessorequivalent: "2272", + lessorgreater: "2276", + lessoverequal: "2266", + lesssmall: "FE64", + lezh: "026E", + lfblock: "258C", + lhookretroflex: "026D", + lira: "20A4", + liwnarmenian: "056C", + lj: "01C9", + ljecyrillic: "0459", + ll: "F6C0", + lladeva: "0933", + llagujarati: "0AB3", + llinebelow: "1E3B", + llladeva: "0934", + llvocalicbengali: "09E1", + llvocalicdeva: "0961", + llvocalicvowelsignbengali: "09E3", + llvocalicvowelsigndeva: "0963", + lmiddletilde: "026B", + lmonospace: "FF4C", + lmsquare: "33D0", + lochulathai: "0E2C", + logicaland: "2227", + logicalnot: "00AC", + logicalnotreversed: "2310", + logicalor: "2228", + lolingthai: "0E25", + longs: "017F", + lowlinecenterline: "FE4E", + lowlinecmb: "0332", + lowlinedashed: "FE4D", + lozenge: "25CA", + lparen: "24A7", + lslash: "0142", + lsquare: "2113", + lsuperior: "F6EE", + ltshade: "2591", + luthai: "0E26", + lvocalicbengali: "098C", + lvocalicdeva: "090C", + lvocalicvowelsignbengali: "09E2", + lvocalicvowelsigndeva: "0962", + lxsquare: "33D3", + m: "006D", + mabengali: "09AE", + macron: "00AF", + macronbelowcmb: "0331", + macroncmb: "0304", + macronlowmod: "02CD", + macronmonospace: "FFE3", + macute: "1E3F", + madeva: "092E", + magujarati: "0AAE", + magurmukhi: "0A2E", + mahapakhhebrew: "05A4", + mahapakhlefthebrew: "05A4", + mahiragana: "307E", + maichattawalowleftthai: "F895", + maichattawalowrightthai: "F894", + maichattawathai: "0E4B", + maichattawaupperleftthai: "F893", + maieklowleftthai: "F88C", + maieklowrightthai: "F88B", + maiekthai: "0E48", + maiekupperleftthai: "F88A", + maihanakatleftthai: "F884", + maihanakatthai: "0E31", + maitaikhuleftthai: "F889", + maitaikhuthai: "0E47", + maitholowleftthai: "F88F", + maitholowrightthai: "F88E", + maithothai: "0E49", + maithoupperleftthai: "F88D", + maitrilowleftthai: "F892", + maitrilowrightthai: "F891", + maitrithai: "0E4A", + maitriupperleftthai: "F890", + maiyamokthai: "0E46", + makatakana: "30DE", + makatakanahalfwidth: "FF8F", + male: "2642", + mansyonsquare: "3347", + maqafhebrew: "05BE", + mars: "2642", + masoracirclehebrew: "05AF", + masquare: "3383", + mbopomofo: "3107", + mbsquare: "33D4", + mcircle: "24DC", + mcubedsquare: "33A5", + mdotaccent: "1E41", + mdotbelow: "1E43", + meemarabic: "0645", + meemfinalarabic: "FEE2", + meeminitialarabic: "FEE3", + meemmedialarabic: "FEE4", + meemmeeminitialarabic: "FCD1", + meemmeemisolatedarabic: "FC48", + meetorusquare: "334D", + mehiragana: "3081", + meizierasquare: "337E", + mekatakana: "30E1", + mekatakanahalfwidth: "FF92", + mem: "05DE", + memdagesh: "FB3E", + memdageshhebrew: "FB3E", + memhebrew: "05DE", + menarmenian: "0574", + merkhahebrew: "05A5", + merkhakefulahebrew: "05A6", + merkhakefulalefthebrew: "05A6", + merkhalefthebrew: "05A5", + mhook: "0271", + mhzsquare: "3392", + middledotkatakanahalfwidth: "FF65", + middot: "00B7", + mieumacirclekorean: "3272", + mieumaparenkorean: "3212", + mieumcirclekorean: "3264", + mieumkorean: "3141", + mieumpansioskorean: "3170", + mieumparenkorean: "3204", + mieumpieupkorean: "316E", + mieumsioskorean: "316F", + mihiragana: "307F", + mikatakana: "30DF", + mikatakanahalfwidth: "FF90", + minus: "2212", + minusbelowcmb: "0320", + minuscircle: "2296", + minusmod: "02D7", + minusplus: "2213", + minute: "2032", + miribaarusquare: "334A", + mirisquare: "3349", + mlonglegturned: "0270", + mlsquare: "3396", + mmcubedsquare: "33A3", + mmonospace: "FF4D", + mmsquaredsquare: "339F", + mohiragana: "3082", + mohmsquare: "33C1", + mokatakana: "30E2", + mokatakanahalfwidth: "FF93", + molsquare: "33D6", + momathai: "0E21", + moverssquare: "33A7", + moverssquaredsquare: "33A8", + mparen: "24A8", + mpasquare: "33AB", + mssquare: "33B3", + msuperior: "F6EF", + mturned: "026F", + mu: "00B5", + mu1: "00B5", + muasquare: "3382", + muchgreater: "226B", + muchless: "226A", + mufsquare: "338C", + mugreek: "03BC", + mugsquare: "338D", + muhiragana: "3080", + mukatakana: "30E0", + mukatakanahalfwidth: "FF91", + mulsquare: "3395", + multiply: "00D7", + mumsquare: "339B", + munahhebrew: "05A3", + munahlefthebrew: "05A3", + musicalnote: "266A", + musicalnotedbl: "266B", + musicflatsign: "266D", + musicsharpsign: "266F", + mussquare: "33B2", + muvsquare: "33B6", + muwsquare: "33BC", + mvmegasquare: "33B9", + mvsquare: "33B7", + mwmegasquare: "33BF", + mwsquare: "33BD", + n: "006E", + nabengali: "09A8", + nabla: "2207", + nacute: "0144", + nadeva: "0928", + nagujarati: "0AA8", + nagurmukhi: "0A28", + nahiragana: "306A", + nakatakana: "30CA", + nakatakanahalfwidth: "FF85", + napostrophe: "0149", + nasquare: "3381", + nbopomofo: "310B", + nbspace: "00A0", + ncaron: "0148", + ncedilla: "0146", + ncircle: "24DD", + ncircumflexbelow: "1E4B", + ncommaaccent: "0146", + ndotaccent: "1E45", + ndotbelow: "1E47", + nehiragana: "306D", + nekatakana: "30CD", + nekatakanahalfwidth: "FF88", + newsheqelsign: "20AA", + nfsquare: "338B", + ngabengali: "0999", + ngadeva: "0919", + ngagujarati: "0A99", + ngagurmukhi: "0A19", + ngonguthai: "0E07", + nhiragana: "3093", + nhookleft: "0272", + nhookretroflex: "0273", + nieunacirclekorean: "326F", + nieunaparenkorean: "320F", + nieuncieuckorean: "3135", + nieuncirclekorean: "3261", + nieunhieuhkorean: "3136", + nieunkorean: "3134", + nieunpansioskorean: "3168", + nieunparenkorean: "3201", + nieunsioskorean: "3167", + nieuntikeutkorean: "3166", + nihiragana: "306B", + nikatakana: "30CB", + nikatakanahalfwidth: "FF86", + nikhahitleftthai: "F899", + nikhahitthai: "0E4D", + nine: "0039", + ninearabic: "0669", + ninebengali: "09EF", + ninecircle: "2468", + ninecircleinversesansserif: "2792", + ninedeva: "096F", + ninegujarati: "0AEF", + ninegurmukhi: "0A6F", + ninehackarabic: "0669", + ninehangzhou: "3029", + nineideographicparen: "3228", + nineinferior: "2089", + ninemonospace: "FF19", + nineoldstyle: "F739", + nineparen: "247C", + nineperiod: "2490", + ninepersian: "06F9", + nineroman: "2178", + ninesuperior: "2079", + nineteencircle: "2472", + nineteenparen: "2486", + nineteenperiod: "249A", + ninethai: "0E59", + nj: "01CC", + njecyrillic: "045A", + nkatakana: "30F3", + nkatakanahalfwidth: "FF9D", + nlegrightlong: "019E", + nlinebelow: "1E49", + nmonospace: "FF4E", + nmsquare: "339A", + nnabengali: "09A3", + nnadeva: "0923", + nnagujarati: "0AA3", + nnagurmukhi: "0A23", + nnnadeva: "0929", + nohiragana: "306E", + nokatakana: "30CE", + nokatakanahalfwidth: "FF89", + nonbreakingspace: "00A0", + nonenthai: "0E13", + nonuthai: "0E19", + noonarabic: "0646", + noonfinalarabic: "FEE6", + noonghunnaarabic: "06BA", + noonghunnafinalarabic: "FB9F", + noonhehinitialarabic: "FEE7 FEEC", + nooninitialarabic: "FEE7", + noonjeeminitialarabic: "FCD2", + noonjeemisolatedarabic: "FC4B", + noonmedialarabic: "FEE8", + noonmeeminitialarabic: "FCD5", + noonmeemisolatedarabic: "FC4E", + noonnoonfinalarabic: "FC8D", + notcontains: "220C", + notelement: "2209", + notelementof: "2209", + notequal: "2260", + notgreater: "226F", + notgreaternorequal: "2271", + notgreaternorless: "2279", + notidentical: "2262", + notless: "226E", + notlessnorequal: "2270", + notparallel: "2226", + notprecedes: "2280", + notsubset: "2284", + notsucceeds: "2281", + notsuperset: "2285", + nowarmenian: "0576", + nparen: "24A9", + nssquare: "33B1", + nsuperior: "207F", + ntilde: "00F1", + nu: "03BD", + nuhiragana: "306C", + nukatakana: "30CC", + nukatakanahalfwidth: "FF87", + nuktabengali: "09BC", + nuktadeva: "093C", + nuktagujarati: "0ABC", + nuktagurmukhi: "0A3C", + numbersign: "0023", + numbersignmonospace: "FF03", + numbersignsmall: "FE5F", + numeralsigngreek: "0374", + numeralsignlowergreek: "0375", + numero: "2116", + nun: "05E0", + nundagesh: "FB40", + nundageshhebrew: "FB40", + nunhebrew: "05E0", + nvsquare: "33B5", + nwsquare: "33BB", + nyabengali: "099E", + nyadeva: "091E", + nyagujarati: "0A9E", + nyagurmukhi: "0A1E", + o: "006F", + oacute: "00F3", + oangthai: "0E2D", + obarred: "0275", + obarredcyrillic: "04E9", + obarreddieresiscyrillic: "04EB", + obengali: "0993", + obopomofo: "311B", + obreve: "014F", + ocandradeva: "0911", + ocandragujarati: "0A91", + ocandravowelsigndeva: "0949", + ocandravowelsigngujarati: "0AC9", + ocaron: "01D2", + ocircle: "24DE", + ocircumflex: "00F4", + ocircumflexacute: "1ED1", + ocircumflexdotbelow: "1ED9", + ocircumflexgrave: "1ED3", + ocircumflexhookabove: "1ED5", + ocircumflextilde: "1ED7", + ocyrillic: "043E", + odblacute: "0151", + odblgrave: "020D", + odeva: "0913", + odieresis: "00F6", + odieresiscyrillic: "04E7", + odotbelow: "1ECD", + oe: "0153", + oekorean: "315A", + ogonek: "02DB", + ogonekcmb: "0328", + ograve: "00F2", + ogujarati: "0A93", + oharmenian: "0585", + ohiragana: "304A", + ohookabove: "1ECF", + ohorn: "01A1", + ohornacute: "1EDB", + ohorndotbelow: "1EE3", + ohorngrave: "1EDD", + ohornhookabove: "1EDF", + ohorntilde: "1EE1", + ohungarumlaut: "0151", + oi: "01A3", + oinvertedbreve: "020F", + okatakana: "30AA", + okatakanahalfwidth: "FF75", + okorean: "3157", + olehebrew: "05AB", + omacron: "014D", + omacronacute: "1E53", + omacrongrave: "1E51", + omdeva: "0950", + omega: "03C9", + omega1: "03D6", + omegacyrillic: "0461", + omegalatinclosed: "0277", + omegaroundcyrillic: "047B", + omegatitlocyrillic: "047D", + omegatonos: "03CE", + omgujarati: "0AD0", + omicron: "03BF", + omicrontonos: "03CC", + omonospace: "FF4F", + one: "0031", + onearabic: "0661", + onebengali: "09E7", + onecircle: "2460", + onecircleinversesansserif: "278A", + onedeva: "0967", + onedotenleader: "2024", + oneeighth: "215B", + onefitted: "F6DC", + onegujarati: "0AE7", + onegurmukhi: "0A67", + onehackarabic: "0661", + onehalf: "00BD", + onehangzhou: "3021", + oneideographicparen: "3220", + oneinferior: "2081", + onemonospace: "FF11", + onenumeratorbengali: "09F4", + oneoldstyle: "F731", + oneparen: "2474", + oneperiod: "2488", + onepersian: "06F1", + onequarter: "00BC", + oneroman: "2170", + onesuperior: "00B9", + onethai: "0E51", + onethird: "2153", + oogonek: "01EB", + oogonekmacron: "01ED", + oogurmukhi: "0A13", + oomatragurmukhi: "0A4B", + oopen: "0254", + oparen: "24AA", + openbullet: "25E6", + option: "2325", + ordfeminine: "00AA", + ordmasculine: "00BA", + orthogonal: "221F", + oshortdeva: "0912", + oshortvowelsigndeva: "094A", + oslash: "00F8", + oslashacute: "01FF", + osmallhiragana: "3049", + osmallkatakana: "30A9", + osmallkatakanahalfwidth: "FF6B", + ostrokeacute: "01FF", + osuperior: "F6F0", + otcyrillic: "047F", + otilde: "00F5", + otildeacute: "1E4D", + otildedieresis: "1E4F", + oubopomofo: "3121", + overline: "203E", + overlinecenterline: "FE4A", + overlinecmb: "0305", + overlinedashed: "FE49", + overlinedblwavy: "FE4C", + overlinewavy: "FE4B", + overscore: "00AF", + ovowelsignbengali: "09CB", + ovowelsigndeva: "094B", + ovowelsigngujarati: "0ACB", + p: "0070", + paampssquare: "3380", + paasentosquare: "332B", + pabengali: "09AA", + pacute: "1E55", + padeva: "092A", + pagedown: "21DF", + pageup: "21DE", + pagujarati: "0AAA", + pagurmukhi: "0A2A", + pahiragana: "3071", + paiyannoithai: "0E2F", + pakatakana: "30D1", + palatalizationcyrilliccmb: "0484", + palochkacyrillic: "04C0", + pansioskorean: "317F", + paragraph: "00B6", + parallel: "2225", + parenleft: "0028", + parenleftaltonearabic: "FD3E", + parenleftbt: "F8ED", + parenleftex: "F8EC", + parenleftinferior: "208D", + parenleftmonospace: "FF08", + parenleftsmall: "FE59", + parenleftsuperior: "207D", + parenlefttp: "F8EB", + parenleftvertical: "FE35", + parenright: "0029", + parenrightaltonearabic: "FD3F", + parenrightbt: "F8F8", + parenrightex: "F8F7", + parenrightinferior: "208E", + parenrightmonospace: "FF09", + parenrightsmall: "FE5A", + parenrightsuperior: "207E", + parenrighttp: "F8F6", + parenrightvertical: "FE36", + partialdiff: "2202", + paseqhebrew: "05C0", + pashtahebrew: "0599", + pasquare: "33A9", + patah: "05B7", + patah11: "05B7", + patah1d: "05B7", + patah2a: "05B7", + patahhebrew: "05B7", + patahnarrowhebrew: "05B7", + patahquarterhebrew: "05B7", + patahwidehebrew: "05B7", + pazerhebrew: "05A1", + pbopomofo: "3106", + pcircle: "24DF", + pdotaccent: "1E57", + pe: "05E4", + pecyrillic: "043F", + pedagesh: "FB44", + pedageshhebrew: "FB44", + peezisquare: "333B", + pefinaldageshhebrew: "FB43", + peharabic: "067E", + peharmenian: "057A", + pehebrew: "05E4", + pehfinalarabic: "FB57", + pehinitialarabic: "FB58", + pehiragana: "307A", + pehmedialarabic: "FB59", + pekatakana: "30DA", + pemiddlehookcyrillic: "04A7", + perafehebrew: "FB4E", + percent: "0025", + percentarabic: "066A", + percentmonospace: "FF05", + percentsmall: "FE6A", + period: "002E", + periodarmenian: "0589", + periodcentered: "00B7", + periodhalfwidth: "FF61", + periodinferior: "F6E7", + periodmonospace: "FF0E", + periodsmall: "FE52", + periodsuperior: "F6E8", + perispomenigreekcmb: "0342", + perpendicular: "22A5", + perthousand: "2030", + peseta: "20A7", + pfsquare: "338A", + phabengali: "09AB", + phadeva: "092B", + phagujarati: "0AAB", + phagurmukhi: "0A2B", + phi: "03C6", + phi1: "03D5", + phieuphacirclekorean: "327A", + phieuphaparenkorean: "321A", + phieuphcirclekorean: "326C", + phieuphkorean: "314D", + phieuphparenkorean: "320C", + philatin: "0278", + phinthuthai: "0E3A", + phisymbolgreek: "03D5", + phook: "01A5", + phophanthai: "0E1E", + phophungthai: "0E1C", + phosamphaothai: "0E20", + pi: "03C0", + pieupacirclekorean: "3273", + pieupaparenkorean: "3213", + pieupcieuckorean: "3176", + pieupcirclekorean: "3265", + pieupkiyeokkorean: "3172", + pieupkorean: "3142", + pieupparenkorean: "3205", + pieupsioskiyeokkorean: "3174", + pieupsioskorean: "3144", + pieupsiostikeutkorean: "3175", + pieupthieuthkorean: "3177", + pieuptikeutkorean: "3173", + pihiragana: "3074", + pikatakana: "30D4", + pisymbolgreek: "03D6", + piwrarmenian: "0583", + plus: "002B", + plusbelowcmb: "031F", + pluscircle: "2295", + plusminus: "00B1", + plusmod: "02D6", + plusmonospace: "FF0B", + plussmall: "FE62", + plussuperior: "207A", + pmonospace: "FF50", + pmsquare: "33D8", + pohiragana: "307D", + pointingindexdownwhite: "261F", + pointingindexleftwhite: "261C", + pointingindexrightwhite: "261E", + pointingindexupwhite: "261D", + pokatakana: "30DD", + poplathai: "0E1B", + postalmark: "3012", + postalmarkface: "3020", + pparen: "24AB", + precedes: "227A", + prescription: "211E", + primemod: "02B9", + primereversed: "2035", + product: "220F", + projective: "2305", + prolongedkana: "30FC", + propellor: "2318", + propersubset: "2282", + propersuperset: "2283", + proportion: "2237", + proportional: "221D", + psi: "03C8", + psicyrillic: "0471", + psilipneumatacyrilliccmb: "0486", + pssquare: "33B0", + puhiragana: "3077", + pukatakana: "30D7", + pvsquare: "33B4", + pwsquare: "33BA", + q: "0071", + qadeva: "0958", + qadmahebrew: "05A8", + qafarabic: "0642", + qaffinalarabic: "FED6", + qafinitialarabic: "FED7", + qafmedialarabic: "FED8", + qamats: "05B8", + qamats10: "05B8", + qamats1a: "05B8", + qamats1c: "05B8", + qamats27: "05B8", + qamats29: "05B8", + qamats33: "05B8", + qamatsde: "05B8", + qamatshebrew: "05B8", + qamatsnarrowhebrew: "05B8", + qamatsqatanhebrew: "05B8", + qamatsqatannarrowhebrew: "05B8", + qamatsqatanquarterhebrew: "05B8", + qamatsqatanwidehebrew: "05B8", + qamatsquarterhebrew: "05B8", + qamatswidehebrew: "05B8", + qarneyparahebrew: "059F", + qbopomofo: "3111", + qcircle: "24E0", + qhook: "02A0", + qmonospace: "FF51", + qof: "05E7", + qofdagesh: "FB47", + qofdageshhebrew: "FB47", + qofhatafpatah: "05E7 05B2", + qofhatafpatahhebrew: "05E7 05B2", + qofhatafsegol: "05E7 05B1", + qofhatafsegolhebrew: "05E7 05B1", + qofhebrew: "05E7", + 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: "24AC", + quarternote: "2669", + qubuts: "05BB", + qubuts18: "05BB", + qubuts25: "05BB", + qubuts31: "05BB", + qubutshebrew: "05BB", + qubutsnarrowhebrew: "05BB", + qubutsquarterhebrew: "05BB", + qubutswidehebrew: "05BB", + question: "003F", + questionarabic: "061F", + questionarmenian: "055E", + questiondown: "00BF", + questiondownsmall: "F7BF", + questiongreek: "037E", + questionmonospace: "FF1F", + questionsmall: "F73F", + quotedbl: "0022", + quotedblbase: "201E", + quotedblleft: "201C", + quotedblmonospace: "FF02", + quotedblprime: "301E", + quotedblprimereversed: "301D", + quotedblright: "201D", + quoteleft: "2018", + quoteleftreversed: "201B", + quotereversed: "201B", + quoteright: "2019", + quoterightn: "0149", + quotesinglbase: "201A", + quotesingle: "0027", + quotesinglemonospace: "FF07", + r: "0072", + raarmenian: "057C", + rabengali: "09B0", + racute: "0155", + radeva: "0930", + radical: "221A", + radicalex: "F8E5", + radoverssquare: "33AE", + radoverssquaredsquare: "33AF", + radsquare: "33AD", + rafe: "05BF", + rafehebrew: "05BF", + ragujarati: "0AB0", + ragurmukhi: "0A30", + rahiragana: "3089", + rakatakana: "30E9", + rakatakanahalfwidth: "FF97", + ralowerdiagonalbengali: "09F1", + ramiddlediagonalbengali: "09F0", + ramshorn: "0264", + ratio: "2236", + rbopomofo: "3116", + rcaron: "0159", + rcedilla: "0157", + rcircle: "24E1", + rcommaaccent: "0157", + rdblgrave: "0211", + rdotaccent: "1E59", + rdotbelow: "1E5B", + rdotbelowmacron: "1E5D", + referencemark: "203B", + reflexsubset: "2286", + reflexsuperset: "2287", + registered: "00AE", + registersans: "F8E8", + registerserif: "F6DA", + reharabic: "0631", + reharmenian: "0580", + rehfinalarabic: "FEAE", + rehiragana: "308C", + rehyehaleflamarabic: "0631 FEF3 FE8E 0644", + rekatakana: "30EC", + rekatakanahalfwidth: "FF9A", + resh: "05E8", + reshdageshhebrew: "FB48", + reshhatafpatah: "05E8 05B2", + reshhatafpatahhebrew: "05E8 05B2", + reshhatafsegol: "05E8 05B1", + reshhatafsegolhebrew: "05E8 05B1", + reshhebrew: "05E8", + 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: "223D", + reviahebrew: "0597", + reviamugrashhebrew: "0597", + revlogicalnot: "2310", + rfishhook: "027E", + rfishhookreversed: "027F", + rhabengali: "09DD", + rhadeva: "095D", + rho: "03C1", + rhook: "027D", + rhookturned: "027B", + rhookturnedsuperior: "02B5", + rhosymbolgreek: "03F1", + rhotichookmod: "02DE", + rieulacirclekorean: "3271", + rieulaparenkorean: "3211", + rieulcirclekorean: "3263", + rieulhieuhkorean: "3140", + rieulkiyeokkorean: "313A", + rieulkiyeoksioskorean: "3169", + rieulkorean: "3139", + rieulmieumkorean: "313B", + rieulpansioskorean: "316C", + rieulparenkorean: "3203", + rieulphieuphkorean: "313F", + rieulpieupkorean: "313C", + rieulpieupsioskorean: "316B", + rieulsioskorean: "313D", + rieulthieuthkorean: "313E", + rieultikeutkorean: "316A", + rieulyeorinhieuhkorean: "316D", + rightangle: "221F", + righttackbelowcmb: "0319", + righttriangle: "22BF", + rihiragana: "308A", + rikatakana: "30EA", + rikatakanahalfwidth: "FF98", + ring: "02DA", + ringbelowcmb: "0325", + ringcmb: "030A", + ringhalfleft: "02BF", + ringhalfleftarmenian: "0559", + ringhalfleftbelowcmb: "031C", + ringhalfleftcentered: "02D3", + ringhalfright: "02BE", + ringhalfrightbelowcmb: "0339", + ringhalfrightcentered: "02D2", + rinvertedbreve: "0213", + rittorusquare: "3351", + rlinebelow: "1E5F", + rlongleg: "027C", + rlonglegturned: "027A", + rmonospace: "FF52", + rohiragana: "308D", + rokatakana: "30ED", + rokatakanahalfwidth: "FF9B", + roruathai: "0E23", + rparen: "24AD", + rrabengali: "09DC", + rradeva: "0931", + rragurmukhi: "0A5C", + rreharabic: "0691", + rrehfinalarabic: "FB8D", + rrvocalicbengali: "09E0", + rrvocalicdeva: "0960", + rrvocalicgujarati: "0AE0", + rrvocalicvowelsignbengali: "09C4", + rrvocalicvowelsigndeva: "0944", + rrvocalicvowelsigngujarati: "0AC4", + rsuperior: "F6F1", + rtblock: "2590", + rturned: "0279", + rturnedsuperior: "02B4", + ruhiragana: "308B", + rukatakana: "30EB", + rukatakanahalfwidth: "FF99", + rupeemarkbengali: "09F2", + rupeesignbengali: "09F3", + rupiah: "F6DD", + ruthai: "0E24", + rvocalicbengali: "098B", + rvocalicdeva: "090B", + rvocalicgujarati: "0A8B", + rvocalicvowelsignbengali: "09C3", + rvocalicvowelsigndeva: "0943", + rvocalicvowelsigngujarati: "0AC3", + s: "0073", + sabengali: "09B8", + sacute: "015B", + sacutedotaccent: "1E65", + sadarabic: "0635", + sadeva: "0938", + sadfinalarabic: "FEBA", + sadinitialarabic: "FEBB", + sadmedialarabic: "FEBC", + sagujarati: "0AB8", + sagurmukhi: "0A38", + sahiragana: "3055", + sakatakana: "30B5", + sakatakanahalfwidth: "FF7B", + sallallahoualayhewasallamarabic: "FDFA", + samekh: "05E1", + samekhdagesh: "FB41", + samekhdageshhebrew: "FB41", + samekhhebrew: "05E1", + saraaathai: "0E32", + saraaethai: "0E41", + saraaimaimalaithai: "0E44", + saraaimaimuanthai: "0E43", + saraamthai: "0E33", + saraathai: "0E30", + saraethai: "0E40", + saraiileftthai: "F886", + saraiithai: "0E35", + saraileftthai: "F885", + saraithai: "0E34", + saraothai: "0E42", + saraueeleftthai: "F888", + saraueethai: "0E37", + saraueleftthai: "F887", + sarauethai: "0E36", + sarauthai: "0E38", + sarauuthai: "0E39", + sbopomofo: "3119", + scaron: "0161", + scarondotaccent: "1E67", + scedilla: "015F", + schwa: "0259", + schwacyrillic: "04D9", + schwadieresiscyrillic: "04DB", + schwahook: "025A", + scircle: "24E2", + scircumflex: "015D", + scommaaccent: "0219", + sdotaccent: "1E61", + sdotbelow: "1E63", + sdotbelowdotaccent: "1E69", + seagullbelowcmb: "033C", + second: "2033", + secondtonechinese: "02CA", + section: "00A7", + seenarabic: "0633", + seenfinalarabic: "FEB2", + seeninitialarabic: "FEB3", + seenmedialarabic: "FEB4", + segol: "05B6", + segol13: "05B6", + segol1f: "05B6", + segol2c: "05B6", + segolhebrew: "05B6", + segolnarrowhebrew: "05B6", + segolquarterhebrew: "05B6", + segoltahebrew: "0592", + segolwidehebrew: "05B6", + seharmenian: "057D", + sehiragana: "305B", + sekatakana: "30BB", + sekatakanahalfwidth: "FF7E", + semicolon: "003B", + semicolonarabic: "061B", + semicolonmonospace: "FF1B", + semicolonsmall: "FE54", + semivoicedmarkkana: "309C", + semivoicedmarkkanahalfwidth: "FF9F", + sentisquare: "3322", + sentosquare: "3323", + seven: "0037", + sevenarabic: "0667", + sevenbengali: "09ED", + sevencircle: "2466", + sevencircleinversesansserif: "2790", + sevendeva: "096D", + seveneighths: "215E", + sevengujarati: "0AED", + sevengurmukhi: "0A6D", + sevenhackarabic: "0667", + sevenhangzhou: "3027", + sevenideographicparen: "3226", + seveninferior: "2087", + sevenmonospace: "FF17", + sevenoldstyle: "F737", + sevenparen: "247A", + sevenperiod: "248E", + sevenpersian: "06F7", + sevenroman: "2176", + sevensuperior: "2077", + seventeencircle: "2470", + seventeenparen: "2484", + seventeenperiod: "2498", + seventhai: "0E57", + sfthyphen: "00AD", + shaarmenian: "0577", + shabengali: "09B6", + shacyrillic: "0448", + shaddaarabic: "0651", + shaddadammaarabic: "FC61", + shaddadammatanarabic: "FC5E", + shaddafathaarabic: "FC60", + shaddafathatanarabic: "0651 064B", + shaddakasraarabic: "FC62", + shaddakasratanarabic: "FC5F", + shade: "2592", + shadedark: "2593", + shadelight: "2591", + shademedium: "2592", + shadeva: "0936", + shagujarati: "0AB6", + shagurmukhi: "0A36", + shalshelethebrew: "0593", + shbopomofo: "3115", + shchacyrillic: "0449", + sheenarabic: "0634", + sheenfinalarabic: "FEB6", + sheeninitialarabic: "FEB7", + sheenmedialarabic: "FEB8", + sheicoptic: "03E3", + sheqel: "20AA", + sheqelhebrew: "20AA", + sheva: "05B0", + sheva115: "05B0", + sheva15: "05B0", + sheva22: "05B0", + sheva2e: "05B0", + shevahebrew: "05B0", + shevanarrowhebrew: "05B0", + shevaquarterhebrew: "05B0", + shevawidehebrew: "05B0", + shhacyrillic: "04BB", + shimacoptic: "03ED", + shin: "05E9", + shindagesh: "FB49", + shindageshhebrew: "FB49", + shindageshshindot: "FB2C", + shindageshshindothebrew: "FB2C", + shindageshsindot: "FB2D", + shindageshsindothebrew: "FB2D", + shindothebrew: "05C1", + shinhebrew: "05E9", + shinshindot: "FB2A", + shinshindothebrew: "FB2A", + shinsindot: "FB2B", + shinsindothebrew: "FB2B", + shook: "0282", + sigma: "03C3", + sigma1: "03C2", + sigmafinal: "03C2", + sigmalunatesymbolgreek: "03F2", + sihiragana: "3057", + sikatakana: "30B7", + sikatakanahalfwidth: "FF7C", + siluqhebrew: "05BD", + siluqlefthebrew: "05BD", + similar: "223C", + sindothebrew: "05C2", + siosacirclekorean: "3274", + siosaparenkorean: "3214", + sioscieuckorean: "317E", + sioscirclekorean: "3266", + sioskiyeokkorean: "317A", + sioskorean: "3145", + siosnieunkorean: "317B", + siosparenkorean: "3206", + siospieupkorean: "317D", + siostikeutkorean: "317C", + six: "0036", + sixarabic: "0666", + sixbengali: "09EC", + sixcircle: "2465", + sixcircleinversesansserif: "278F", + sixdeva: "096C", + sixgujarati: "0AEC", + sixgurmukhi: "0A6C", + sixhackarabic: "0666", + sixhangzhou: "3026", + sixideographicparen: "3225", + sixinferior: "2086", + sixmonospace: "FF16", + sixoldstyle: "F736", + sixparen: "2479", + sixperiod: "248D", + sixpersian: "06F6", + sixroman: "2175", + sixsuperior: "2076", + sixteencircle: "246F", + sixteencurrencydenominatorbengali: "09F9", + sixteenparen: "2483", + sixteenperiod: "2497", + sixthai: "0E56", + slash: "002F", + slashmonospace: "FF0F", + slong: "017F", + slongdotaccent: "1E9B", + smileface: "263A", + smonospace: "FF53", + sofpasuqhebrew: "05C3", + softhyphen: "00AD", + softsigncyrillic: "044C", + sohiragana: "305D", + sokatakana: "30BD", + sokatakanahalfwidth: "FF7F", + soliduslongoverlaycmb: "0338", + solidusshortoverlaycmb: "0337", + sorusithai: "0E29", + sosalathai: "0E28", + sosothai: "0E0B", + sosuathai: "0E2A", + space: "0020", + spacehackarabic: "0020", + spade: "2660", + spadesuitblack: "2660", + spadesuitwhite: "2664", + sparen: "24AE", + squarebelowcmb: "033B", + squarecc: "33C4", + squarecm: "339D", + squarediagonalcrosshatchfill: "25A9", + squarehorizontalfill: "25A4", + squarekg: "338F", + squarekm: "339E", + squarekmcapital: "33CE", + squareln: "33D1", + squarelog: "33D2", + squaremg: "338E", + squaremil: "33D5", + squaremm: "339C", + squaremsquared: "33A1", + squareorthogonalcrosshatchfill: "25A6", + squareupperlefttolowerrightfill: "25A7", + squareupperrighttolowerleftfill: "25A8", + squareverticalfill: "25A5", + squarewhitewithsmallblack: "25A3", + srsquare: "33DB", + ssabengali: "09B7", + ssadeva: "0937", + ssagujarati: "0AB7", + ssangcieuckorean: "3149", + ssanghieuhkorean: "3185", + ssangieungkorean: "3180", + ssangkiyeokkorean: "3132", + ssangnieunkorean: "3165", + ssangpieupkorean: "3143", + ssangsioskorean: "3146", + ssangtikeutkorean: "3138", + ssuperior: "F6F2", + sterling: "00A3", + sterlingmonospace: "FFE1", + strokelongoverlaycmb: "0336", + strokeshortoverlaycmb: "0335", + subset: "2282", + subsetnotequal: "228A", + subsetorequal: "2286", + succeeds: "227B", + suchthat: "220B", + suhiragana: "3059", + sukatakana: "30B9", + sukatakanahalfwidth: "FF7D", + sukunarabic: "0652", + summation: "2211", + sun: "263C", + superset: "2283", + supersetnotequal: "228B", + supersetorequal: "2287", + svsquare: "33DC", + syouwaerasquare: "337C", + t: "0074", + tabengali: "09A4", + tackdown: "22A4", + tackleft: "22A3", + tadeva: "0924", + tagujarati: "0AA4", + tagurmukhi: "0A24", + taharabic: "0637", + tahfinalarabic: "FEC2", + tahinitialarabic: "FEC3", + tahiragana: "305F", + tahmedialarabic: "FEC4", + taisyouerasquare: "337D", + takatakana: "30BF", + takatakanahalfwidth: "FF80", + tatweelarabic: "0640", + tau: "03C4", + tav: "05EA", + tavdages: "FB4A", + tavdagesh: "FB4A", + tavdageshhebrew: "FB4A", + tavhebrew: "05EA", + tbar: "0167", + tbopomofo: "310A", + tcaron: "0165", + tccurl: "02A8", + tcedilla: "0163", + tcheharabic: "0686", + tchehfinalarabic: "FB7B", + tchehinitialarabic: "FB7C", + tchehmedialarabic: "FB7D", + tchehmeeminitialarabic: "FB7C FEE4", + tcircle: "24E3", + tcircumflexbelow: "1E71", + tcommaaccent: "0163", + tdieresis: "1E97", + tdotaccent: "1E6B", + tdotbelow: "1E6D", + tecyrillic: "0442", + tedescendercyrillic: "04AD", + teharabic: "062A", + tehfinalarabic: "FE96", + tehhahinitialarabic: "FCA2", + tehhahisolatedarabic: "FC0C", + tehinitialarabic: "FE97", + tehiragana: "3066", + tehjeeminitialarabic: "FCA1", + tehjeemisolatedarabic: "FC0B", + tehmarbutaarabic: "0629", + tehmarbutafinalarabic: "FE94", + tehmedialarabic: "FE98", + tehmeeminitialarabic: "FCA4", + tehmeemisolatedarabic: "FC0E", + tehnoonfinalarabic: "FC73", + tekatakana: "30C6", + tekatakanahalfwidth: "FF83", + telephone: "2121", + telephoneblack: "260E", + telishagedolahebrew: "05A0", + telishaqetanahebrew: "05A9", + tencircle: "2469", + tenideographicparen: "3229", + tenparen: "247D", + tenperiod: "2491", + tenroman: "2179", + tesh: "02A7", + tet: "05D8", + tetdagesh: "FB38", + tetdageshhebrew: "FB38", + tethebrew: "05D8", + tetsecyrillic: "04B5", + tevirhebrew: "059B", + tevirlefthebrew: "059B", + thabengali: "09A5", + thadeva: "0925", + thagujarati: "0AA5", + thagurmukhi: "0A25", + thalarabic: "0630", + thalfinalarabic: "FEAC", + thanthakhatlowleftthai: "F898", + thanthakhatlowrightthai: "F897", + thanthakhatthai: "0E4C", + thanthakhatupperleftthai: "F896", + theharabic: "062B", + thehfinalarabic: "FE9A", + thehinitialarabic: "FE9B", + thehmedialarabic: "FE9C", + thereexists: "2203", + therefore: "2234", + theta: "03B8", + theta1: "03D1", + thetasymbolgreek: "03D1", + thieuthacirclekorean: "3279", + thieuthaparenkorean: "3219", + thieuthcirclekorean: "326B", + thieuthkorean: "314C", + thieuthparenkorean: "320B", + thirteencircle: "246C", + thirteenparen: "2480", + thirteenperiod: "2494", + thonangmonthothai: "0E11", + thook: "01AD", + thophuthaothai: "0E12", + thorn: "00FE", + thothahanthai: "0E17", + thothanthai: "0E10", + thothongthai: "0E18", + thothungthai: "0E16", + thousandcyrillic: "0482", + thousandsseparatorarabic: "066C", + thousandsseparatorpersian: "066C", + three: "0033", + threearabic: "0663", + threebengali: "09E9", + threecircle: "2462", + threecircleinversesansserif: "278C", + threedeva: "0969", + threeeighths: "215C", + threegujarati: "0AE9", + threegurmukhi: "0A69", + threehackarabic: "0663", + threehangzhou: "3023", + threeideographicparen: "3222", + threeinferior: "2083", + threemonospace: "FF13", + threenumeratorbengali: "09F6", + threeoldstyle: "F733", + threeparen: "2476", + threeperiod: "248A", + threepersian: "06F3", + threequarters: "00BE", + threequartersemdash: "F6DE", + threeroman: "2172", + threesuperior: "00B3", + threethai: "0E53", + thzsquare: "3394", + tihiragana: "3061", + tikatakana: "30C1", + tikatakanahalfwidth: "FF81", + tikeutacirclekorean: "3270", + tikeutaparenkorean: "3210", + tikeutcirclekorean: "3262", + tikeutkorean: "3137", + tikeutparenkorean: "3202", + tilde: "02DC", + tildebelowcmb: "0330", + tildecmb: "0303", + tildecomb: "0303", + tildedoublecmb: "0360", + tildeoperator: "223C", + tildeoverlaycmb: "0334", + tildeverticalcmb: "033E", + timescircle: "2297", + tipehahebrew: "0596", + tipehalefthebrew: "0596", + tippigurmukhi: "0A70", + titlocyrilliccmb: "0483", + tiwnarmenian: "057F", + tlinebelow: "1E6F", + tmonospace: "FF54", + toarmenian: "0569", + tohiragana: "3068", + tokatakana: "30C8", + tokatakanahalfwidth: "FF84", + tonebarextrahighmod: "02E5", + tonebarextralowmod: "02E9", + tonebarhighmod: "02E6", + tonebarlowmod: "02E8", + tonebarmidmod: "02E7", + tonefive: "01BD", + tonesix: "0185", + tonetwo: "01A8", + tonos: "0384", + tonsquare: "3327", + topatakthai: "0E0F", + tortoiseshellbracketleft: "3014", + tortoiseshellbracketleftsmall: "FE5D", + tortoiseshellbracketleftvertical: "FE39", + tortoiseshellbracketright: "3015", + tortoiseshellbracketrightsmall: "FE5E", + tortoiseshellbracketrightvertical: "FE3A", + totaothai: "0E15", + tpalatalhook: "01AB", + tparen: "24AF", + trademark: "2122", + trademarksans: "F8EA", + trademarkserif: "F6DB", + tretroflexhook: "0288", + triagdn: "25BC", + triaglf: "25C4", + triagrt: "25BA", + triagup: "25B2", + ts: "02A6", + tsadi: "05E6", + tsadidagesh: "FB46", + tsadidageshhebrew: "FB46", + tsadihebrew: "05E6", + tsecyrillic: "0446", + tsere: "05B5", + tsere12: "05B5", + tsere1e: "05B5", + tsere2b: "05B5", + tserehebrew: "05B5", + tserenarrowhebrew: "05B5", + tserequarterhebrew: "05B5", + tserewidehebrew: "05B5", + tshecyrillic: "045B", + tsuperior: "F6F3", + ttabengali: "099F", + ttadeva: "091F", + ttagujarati: "0A9F", + ttagurmukhi: "0A1F", + tteharabic: "0679", + ttehfinalarabic: "FB67", + ttehinitialarabic: "FB68", + ttehmedialarabic: "FB69", + tthabengali: "09A0", + tthadeva: "0920", + tthagujarati: "0AA0", + tthagurmukhi: "0A20", + tturned: "0287", + tuhiragana: "3064", + tukatakana: "30C4", + tukatakanahalfwidth: "FF82", + tusmallhiragana: "3063", + tusmallkatakana: "30C3", + tusmallkatakanahalfwidth: "FF6F", + twelvecircle: "246B", + twelveparen: "247F", + twelveperiod: "2493", + twelveroman: "217B", + twentycircle: "2473", + twentyhangzhou: "5344", + twentyparen: "2487", + twentyperiod: "249B", + two: "0032", + twoarabic: "0662", + twobengali: "09E8", + twocircle: "2461", + twocircleinversesansserif: "278B", + twodeva: "0968", + twodotenleader: "2025", + twodotleader: "2025", + twodotleadervertical: "FE30", + twogujarati: "0AE8", + twogurmukhi: "0A68", + twohackarabic: "0662", + twohangzhou: "3022", + twoideographicparen: "3221", + twoinferior: "2082", + twomonospace: "FF12", + twonumeratorbengali: "09F5", + twooldstyle: "F732", + twoparen: "2475", + twoperiod: "2489", + twopersian: "06F2", + tworoman: "2171", + twostroke: "01BB", + twosuperior: "00B2", + twothai: "0E52", + twothirds: "2154", + u: "0075", + uacute: "00FA", + ubar: "0289", + ubengali: "0989", + ubopomofo: "3128", + ubreve: "016D", + ucaron: "01D4", + ucircle: "24E4", + ucircumflex: "00FB", + ucircumflexbelow: "1E77", + ucyrillic: "0443", + udattadeva: "0951", + udblacute: "0171", + udblgrave: "0215", + udeva: "0909", + udieresis: "00FC", + udieresisacute: "01D8", + udieresisbelow: "1E73", + udieresiscaron: "01DA", + udieresiscyrillic: "04F1", + udieresisgrave: "01DC", + udieresismacron: "01D6", + udotbelow: "1EE5", + ugrave: "00F9", + ugujarati: "0A89", + ugurmukhi: "0A09", + uhiragana: "3046", + uhookabove: "1EE7", + uhorn: "01B0", + uhornacute: "1EE9", + uhorndotbelow: "1EF1", + uhorngrave: "1EEB", + uhornhookabove: "1EED", + uhorntilde: "1EEF", + uhungarumlaut: "0171", + uhungarumlautcyrillic: "04F3", + uinvertedbreve: "0217", + ukatakana: "30A6", + ukatakanahalfwidth: "FF73", + ukcyrillic: "0479", + ukorean: "315C", + umacron: "016B", + umacroncyrillic: "04EF", + umacrondieresis: "1E7B", + umatragurmukhi: "0A41", + umonospace: "FF55", + underscore: "005F", + underscoredbl: "2017", + underscoremonospace: "FF3F", + underscorevertical: "FE33", + underscorewavy: "FE4F", + union: "222A", + universal: "2200", + uogonek: "0173", + uparen: "24B0", + upblock: "2580", + upperdothebrew: "05C4", + upsilon: "03C5", + upsilondieresis: "03CB", + upsilondieresistonos: "03B0", + upsilonlatin: "028A", + upsilontonos: "03CD", + uptackbelowcmb: "031D", + uptackmod: "02D4", + uragurmukhi: "0A73", + uring: "016F", + ushortcyrillic: "045E", + usmallhiragana: "3045", + usmallkatakana: "30A5", + usmallkatakanahalfwidth: "FF69", + ustraightcyrillic: "04AF", + ustraightstrokecyrillic: "04B1", + utilde: "0169", + utildeacute: "1E79", + utildebelow: "1E75", + uubengali: "098A", + uudeva: "090A", + uugujarati: "0A8A", + uugurmukhi: "0A0A", + uumatragurmukhi: "0A42", + uuvowelsignbengali: "09C2", + uuvowelsigndeva: "0942", + uuvowelsigngujarati: "0AC2", + uvowelsignbengali: "09C1", + uvowelsigndeva: "0941", + uvowelsigngujarati: "0AC1", + v: "0076", + vadeva: "0935", + vagujarati: "0AB5", + vagurmukhi: "0A35", + vakatakana: "30F7", + vav: "05D5", + vavdagesh: "FB35", + vavdagesh65: "FB35", + vavdageshhebrew: "FB35", + vavhebrew: "05D5", + vavholam: "FB4B", + vavholamhebrew: "FB4B", + vavvavhebrew: "05F0", + vavyodhebrew: "05F1", + vcircle: "24E5", + vdotbelow: "1E7F", + vecyrillic: "0432", + veharabic: "06A4", + vehfinalarabic: "FB6B", + vehinitialarabic: "FB6C", + vehmedialarabic: "FB6D", + vekatakana: "30F9", + venus: "2640", + verticalbar: "007C", + verticallineabovecmb: "030D", + verticallinebelowcmb: "0329", + verticallinelowmod: "02CC", + verticallinemod: "02C8", + vewarmenian: "057E", + vhook: "028B", + vikatakana: "30F8", + viramabengali: "09CD", + viramadeva: "094D", + viramagujarati: "0ACD", + visargabengali: "0983", + visargadeva: "0903", + visargagujarati: "0A83", + vmonospace: "FF56", + voarmenian: "0578", + voicediterationhiragana: "309E", + voicediterationkatakana: "30FE", + voicedmarkkana: "309B", + voicedmarkkanahalfwidth: "FF9E", + vokatakana: "30FA", + vparen: "24B1", + vtilde: "1E7D", + vturned: "028C", + vuhiragana: "3094", + vukatakana: "30F4", + w: "0077", + wacute: "1E83", + waekorean: "3159", + wahiragana: "308F", + wakatakana: "30EF", + wakatakanahalfwidth: "FF9C", + wakorean: "3158", + wasmallhiragana: "308E", + wasmallkatakana: "30EE", + wattosquare: "3357", + wavedash: "301C", + wavyunderscorevertical: "FE34", + wawarabic: "0648", + wawfinalarabic: "FEEE", + wawhamzaabovearabic: "0624", + wawhamzaabovefinalarabic: "FE86", + wbsquare: "33DD", + wcircle: "24E6", + wcircumflex: "0175", + wdieresis: "1E85", + wdotaccent: "1E87", + wdotbelow: "1E89", + wehiragana: "3091", + weierstrass: "2118", + wekatakana: "30F1", + wekorean: "315E", + weokorean: "315D", + wgrave: "1E81", + whitebullet: "25E6", + whitecircle: "25CB", + whitecircleinverse: "25D9", + whitecornerbracketleft: "300E", + whitecornerbracketleftvertical: "FE43", + whitecornerbracketright: "300F", + whitecornerbracketrightvertical: "FE44", + whitediamond: "25C7", + whitediamondcontainingblacksmalldiamond: "25C8", + whitedownpointingsmalltriangle: "25BF", + whitedownpointingtriangle: "25BD", + whiteleftpointingsmalltriangle: "25C3", + whiteleftpointingtriangle: "25C1", + whitelenticularbracketleft: "3016", + whitelenticularbracketright: "3017", + whiterightpointingsmalltriangle: "25B9", + whiterightpointingtriangle: "25B7", + whitesmallsquare: "25AB", + whitesmilingface: "263A", + whitesquare: "25A1", + whitestar: "2606", + whitetelephone: "260F", + whitetortoiseshellbracketleft: "3018", + whitetortoiseshellbracketright: "3019", + whiteuppointingsmalltriangle: "25B5", + whiteuppointingtriangle: "25B3", + wihiragana: "3090", + wikatakana: "30F0", + wikorean: "315F", + wmonospace: "FF57", + wohiragana: "3092", + wokatakana: "30F2", + wokatakanahalfwidth: "FF66", + won: "20A9", + wonmonospace: "FFE6", + wowaenthai: "0E27", + wparen: "24B2", + wring: "1E98", + wsuperior: "02B7", + wturned: "028D", + wynn: "01BF", + x: "0078", + xabovecmb: "033D", + xbopomofo: "3112", + xcircle: "24E7", + xdieresis: "1E8D", + xdotaccent: "1E8B", + xeharmenian: "056D", + xi: "03BE", + xmonospace: "FF58", + xparen: "24B3", + xsuperior: "02E3", + y: "0079", + yaadosquare: "334E", + yabengali: "09AF", + yacute: "00FD", + yadeva: "092F", + yaekorean: "3152", + yagujarati: "0AAF", + yagurmukhi: "0A2F", + yahiragana: "3084", + yakatakana: "30E4", + yakatakanahalfwidth: "FF94", + yakorean: "3151", + yamakkanthai: "0E4E", + yasmallhiragana: "3083", + yasmallkatakana: "30E3", + yasmallkatakanahalfwidth: "FF6C", + yatcyrillic: "0463", + ycircle: "24E8", + ycircumflex: "0177", + ydieresis: "00FF", + ydotaccent: "1E8F", + ydotbelow: "1EF5", + yeharabic: "064A", + yehbarreearabic: "06D2", + yehbarreefinalarabic: "FBAF", + yehfinalarabic: "FEF2", + yehhamzaabovearabic: "0626", + yehhamzaabovefinalarabic: "FE8A", + yehhamzaaboveinitialarabic: "FE8B", + yehhamzaabovemedialarabic: "FE8C", + yehinitialarabic: "FEF3", + yehmedialarabic: "FEF4", + yehmeeminitialarabic: "FCDD", + yehmeemisolatedarabic: "FC58", + yehnoonfinalarabic: "FC94", + yehthreedotsbelowarabic: "06D1", + yekorean: "3156", + yen: "00A5", + yenmonospace: "FFE5", + yeokorean: "3155", + yeorinhieuhkorean: "3186", + yerahbenyomohebrew: "05AA", + yerahbenyomolefthebrew: "05AA", + yericyrillic: "044B", + yerudieresiscyrillic: "04F9", + yesieungkorean: "3181", + yesieungpansioskorean: "3183", + yesieungsioskorean: "3182", + yetivhebrew: "059A", + ygrave: "1EF3", + yhook: "01B4", + yhookabove: "1EF7", + yiarmenian: "0575", + yicyrillic: "0457", + yikorean: "3162", + yinyang: "262F", + yiwnarmenian: "0582", + ymonospace: "FF59", + yod: "05D9", + yoddagesh: "FB39", + yoddageshhebrew: "FB39", + yodhebrew: "05D9", + yodyodhebrew: "05F2", + yodyodpatahhebrew: "FB1F", + yohiragana: "3088", + yoikorean: "3189", + yokatakana: "30E8", + yokatakanahalfwidth: "FF96", + yokorean: "315B", + yosmallhiragana: "3087", + yosmallkatakana: "30E7", + yosmallkatakanahalfwidth: "FF6E", + yotgreek: "03F3", + yoyaekorean: "3188", + yoyakorean: "3187", + yoyakthai: "0E22", + yoyingthai: "0E0D", + yparen: "24B4", + ypogegrammeni: "037A", + ypogegrammenigreekcmb: "0345", + yr: "01A6", + yring: "1E99", + ysuperior: "02B8", + ytilde: "1EF9", + yturned: "028E", + yuhiragana: "3086", + yuikorean: "318C", + yukatakana: "30E6", + yukatakanahalfwidth: "FF95", + yukorean: "3160", + yusbigcyrillic: "046B", + yusbigiotifiedcyrillic: "046D", + yuslittlecyrillic: "0467", + yuslittleiotifiedcyrillic: "0469", + yusmallhiragana: "3085", + yusmallkatakana: "30E5", + yusmallkatakanahalfwidth: "FF6D", + yuyekorean: "318B", + yuyeokorean: "318A", + yyabengali: "09DF", + yyadeva: "095F", + z: "007A", + zaarmenian: "0566", + zacute: "017A", + zadeva: "095B", + zagurmukhi: "0A5B", + zaharabic: "0638", + zahfinalarabic: "FEC6", + zahinitialarabic: "FEC7", + zahiragana: "3056", + zahmedialarabic: "FEC8", + zainarabic: "0632", + zainfinalarabic: "FEB0", + zakatakana: "30B6", + zaqefgadolhebrew: "0595", + zaqefqatanhebrew: "0594", + zarqahebrew: "0598", + zayin: "05D6", + zayindagesh: "FB36", + zayindageshhebrew: "FB36", + zayinhebrew: "05D6", + zbopomofo: "3117", + zcaron: "017E", + zcircle: "24E9", + zcircumflex: "1E91", + zcurl: "0291", + zdot: "017C", + zdotaccent: "017C", + zdotbelow: "1E93", + zecyrillic: "0437", + zedescendercyrillic: "0499", + zedieresiscyrillic: "04DF", + zehiragana: "305C", + zekatakana: "30BC", + zero: "0030", + zeroarabic: "0660", + zerobengali: "09E6", + zerodeva: "0966", + zerogujarati: "0AE6", + zerogurmukhi: "0A66", + zerohackarabic: "0660", + zeroinferior: "2080", + zeromonospace: "FF10", + zerooldstyle: "F730", + zeropersian: "06F0", + zerosuperior: "2070", + zerothai: "0E50", + zerowidthjoiner: "FEFF", + zerowidthnonjoiner: "200C", + zerowidthspace: "200B", + zeta: "03B6", + zhbopomofo: "3113", + zhearmenian: "056A", + zhebrevecyrillic: "04C2", + zhecyrillic: "0436", + zhedescendercyrillic: "0497", + zhedieresiscyrillic: "04DD", + zihiragana: "3058", + zikatakana: "30B8", + zinorhebrew: "05AE", + zlinebelow: "1E95", + zmonospace: "FF5A", + zohiragana: "305E", + zokatakana: "30BE", + zparen: "24B5", + zretroflexhook: "0290", + zstroke: "01B6", + zuhiragana: "305A", + zukatakana: "30BA", +}; diff --git a/test.html b/test.html index b70351f2f..be6887578 100644 --- a/test.html +++ b/test.html @@ -7,6 +7,7 @@ + From ce9224538e205e25315d268ee1526c2cb2063ffd Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 01:51:27 +0200 Subject: [PATCH 27/77] Fix a bunch of errors reported by OTS except the error about 3-0-4 MS symbol in cmap --- PDFFont.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 0eb29d323..ed8df6e3b 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -926,7 +926,7 @@ Type1Font.prototype = { }; // Encode the glyph and add it to the FUX - var r = [[0x40, 0xEA]]; + var r = [[0x40, 0x0E]]; for (var i = 0; i < glyphs.length; i++) { var data = glyphs[i].slice(); var charstring = []; @@ -1102,6 +1102,10 @@ Type1Font.prototype = { var offset = aOffset; // length + // Per spec tables must be 4-bytes align so add some 0x00 if needed + while (aData.length & 3) + aData.push(0x00); + var length = aData.length; // checksum @@ -1216,7 +1220,7 @@ Type1Font.prototype = { 0x00, 0x00, 0x00, 0x00, // checksumAdjustement 0x5F, 0x0F, 0x3C, 0xF5, // magicNumber 0x00, 0x00, // Flags - 0x00, 0x00, // unitsPerEM + 0x00, 0x40, // unitsPerEM (>= 16 && <=16384) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // created 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // modified 0x00, 0x00, // xMin @@ -1255,7 +1259,9 @@ Type1Font.prototype = { 0x00, 0x00, // -reserved- 0x00, 0x00 // metricDataFormat ]; - hhea = hhea.concat(this.encodeNumber(charstrings.length, 2)); // numberOfHMetrics + hhea = hhea.concat(this.integerToBytes(charstrings.length, 2)); // numberOfHMetrics + log(hhea); + var tableEntry = this.createTableEntry("hhea", virtualOffset, hhea); otf.set(tableEntry, currentOffset); currentOffset += tableEntry.length; From fdacb575c5601a205cdfc0c2d050ab57a536e0ef Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 01:56:21 +0200 Subject: [PATCH 28/77] Default the unit per EM size to 1000 --- PDFFont.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PDFFont.js b/PDFFont.js index ed8df6e3b..f96e3f04d 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1220,7 +1220,7 @@ Type1Font.prototype = { 0x00, 0x00, 0x00, 0x00, // checksumAdjustement 0x5F, 0x0F, 0x3C, 0xF5, // magicNumber 0x00, 0x00, // Flags - 0x00, 0x40, // unitsPerEM (>= 16 && <=16384) + 0x03, 0xE8, // unitsPerEM (>= 16 && <=16384) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // created 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // modified 0x00, 0x00, // xMin From 828367a1b45e47643a763ff996c138f8bf8c729b Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 03:00:45 +0200 Subject: [PATCH 29/77] Make the Type1 to OTF code active, even if the sanitizer prevent fonts to load at the moment --- PDFFont.js | 86 +++++++++++++++++++++++++++++++++++++----------------- pdf.js | 5 ++-- 2 files changed, 63 insertions(+), 28 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index f96e3f04d..1da594e28 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,3 +1,6 @@ + +var kMaxFontFileSize = 100000; + /** * This dictionary holds decoded fonts data. */ @@ -68,7 +71,13 @@ var TrueTypeFont = function(aFontName, aFontFile) { return; _Fonts[aFontName] = true; - //log("Loading a TrueType font: " + aFontName); + var debug = false; + function dump(aMsg) { + if (debug) + log(aMsg); + } + + dump("Loading a TrueType font: " + aFontName); var fontData = Base64Encoder.encode(aFontFile); Fonts.set(aFontName, fontData); @@ -648,6 +657,12 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { operandStack.push("rmoveto"); break; + case "div": + var num2 = operandStack.pop(); + var num1 = operandStack.pop(); + operandStack.push(num2 / num1); + break; + case "setcurrentpoint": case "dotsection": case "seac": @@ -680,7 +695,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var count = operandStack.pop(); var data = operandStack.pop(); if (index != 3) - log("callothersubr for index: " + index); + dump("callothersubr for index: " + index); operandStack.push(3); operandStack.push("callothersubr"); break; @@ -713,7 +728,7 @@ var Type1Font = function(aFontName, aFontFile) { if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); - if (!type1hack) { + if (!type1hack || true) { type1hack = true; var start = Date.now(); @@ -723,7 +738,13 @@ var Type1Font = function(aFontName, aFontFile) { this.parser = new Type1Parser(ASCIIStream, binaryStream); var fontName = this.parser.parse(); var font = Fonts.get(fontName); - this.convertToOTF(this.convertToCFF(font), font); + var fontData = this.convertToOTF(this.convertToCFF(font), font); + fontData = Base64Encoder.encode(fontData); + Fonts.set(aFontName, fontData); + + // Add the css rule + var url = "url(data:font/otf;base64," + fontData + ");"; + document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); var end = Date.now(); log("Time to parse font is:" + (end - start)); @@ -846,6 +867,12 @@ Type1Font.prototype = { }, convertToCFF: function(aFont) { + var debug = false; + function dump(aMsg) { + if (debug) + log(aMsg); + }; + var charstrings = this.getOrderedCharStrings(aFont); var defaultWidth = this.getDefaultWidth(charstrings); @@ -856,7 +883,7 @@ Type1Font.prototype = { var subrs = aFont.get("Private").get("Subrs"); var parser = new Type1Parser(); for (var i = 0; i < charstrings.length; i++) { - var charstring = charstrings[i].charstring; + var charstring = charstrings[i].charstring.slice(); var glyph = charstrings[i].glyph; if (glyphsChecker[glyph]) error("glyphs already exists!"); @@ -867,10 +894,10 @@ Type1Font.prototype = { charstringsCount++; charstringsDataLength += flattened.length; } - //log("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")"); + dump("There is " + charstringsCount + " glyphs (size: " + charstringsDataLength + ")"); // Create a CFF font data - var cff = new Uint8Array(20000); + var cff = new Uint8Array(kMaxFontFileSize); var currentOffset = 0; // Font header (major version, minor version, header size, offset size) @@ -938,7 +965,12 @@ Type1Font.prototype = { error(c); charstring.push(token); } else { - var bytes = this.encodeNumber(c); + try { + var bytes = this.encodeNumber(c); + } catch(e) { + log("Glyph " + i + " has a wrong value: " + c + " in charstring: " + data); + log("the default value is glyph " + charstrings[i].glyph + " and is supposed to be: " + charstrings[i].charstring); + } for (var k = 0; k < bytes.length; k++) charstring.push(bytes[k]); } @@ -1035,20 +1067,17 @@ Type1Font.prototype = { currentOffset += shit.length; - log("==================== debug ===================="); - /* - log("== parse"); - var file = new Uint8Array(cff, 0, currentOffset); - var parser = new Type2Parser(); - parser.parse(new Stream(file)); - */ + dump("==================== debug ===================="); + //var file = new Uint8Array(cff, 0, currentOffset); + //var parser = new Type2Parser(); + //parser.parse(new Stream(file)); var data = []; for (var i = 0; i < currentOffset; i++) data.push(cff[i]); - log("== write to file"); - writeToFile(data, "/tmp/pdf.js.cff"); + //log("== write to file"); + //writeToFile(data, "/tmp/pdf.js.cff"); return data; }, @@ -1118,7 +1147,7 @@ Type1Font.prototype = { }, convertToOTF: function(aData, aFont) { - var otf = new Uint8Array(20000); + var otf = new Uint8Array(kMaxFontFileSize); var currentOffset = 0; var numTables = 9; @@ -1198,11 +1227,17 @@ Type1Font.prototype = { } for (var i = 0; i < charstrings.length; i++) { - var pos = GlyphsUnicode[charstrings[i].glyph]; + var glyph = charstrings[i].glyph; + if (glyph == ".notdef") + continue; + + var pos = GlyphsUnicode[glyph]; + if (!pos) + error(charstrings[i].glyph + " does not have an entry in the glyphs table"); var b1 = parseInt("0x" + pos[0] + pos[1]); var b2 = parseInt("0x" + pos[2] + pos[3]); - var pos = this.bytesToInteger([b1, b2]); - data[pos] = i + 1; + var num = this.bytesToInteger([b1, b2]); + data[num] = i + 1; } cmap = cmap.concat(data); @@ -1260,7 +1295,6 @@ Type1Font.prototype = { 0x00, 0x00 // metricDataFormat ]; hhea = hhea.concat(this.integerToBytes(charstrings.length, 2)); // numberOfHMetrics - log(hhea); var tableEntry = this.createTableEntry("hhea", virtualOffset, hhea); otf.set(tableEntry, currentOffset); @@ -1336,13 +1370,13 @@ Type1Font.prototype = { otf.set(table, currentOffset); currentOffset += table.length; } - log(currentOffset + "::" + virtualOffset + "\n"); - var data = []; + var fontData = []; for (var i = 0; i < currentOffset; i++) - data.push(otf[i]); + fontData.push(otf[i]); - writeToFile(data, "/tmp/pdf.js.otf"); + //writeToFile(data, "/tmp/pdf.js.otf"); + return fontData; } }; diff --git a/pdf.js b/pdf.js index ef8a18861..7bc788e20 100644 --- a/pdf.js +++ b/pdf.js @@ -2276,7 +2276,7 @@ var CanvasGraphics = (function() { if (!font) return; - var fontName = "Nimbus Roman No9 L"; + var fontName = ""; var subtype = font.get("Subtype").name; switch (subtype) { case "Type1": @@ -2285,7 +2285,8 @@ var CanvasGraphics = (function() { // XXX fetchIfRef looks expensive var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); - font = new Type1Font(fontDescriptor.get("FontName").name, fontFile); + fontName = fontDescriptor.get("FontName").name; + font = new Type1Font(fontName, fontFile); } break; From 632fcfed18fdfaaec728b2281cb5e270cee8f105 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 03:10:54 +0200 Subject: [PATCH 30/77] Turn on TrueType decoder even if the sanitizer prevent them to load at the moment --- PDFFont.js | 4 ++-- pdf.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 1da594e28..fa4faabdd 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -60,7 +60,7 @@ var Base64Encoder = { var str = []; var count = aData.length; for (var i = 0; i < count; i++) - str.push(aData.getChar ? aData.getChar : String.fromCharCode(aData[i])); + str.push(aData.getChar ? aData.getChar() : String.fromCharCode(aData[i])); return window.btoa(str.join("")); } @@ -71,7 +71,7 @@ var TrueTypeFont = function(aFontName, aFontFile) { return; _Fonts[aFontName] = true; - var debug = false; + var debug = true; function dump(aMsg) { if (debug) log(aMsg); diff --git a/pdf.js b/pdf.js index 7bc788e20..cdc035c28 100644 --- a/pdf.js +++ b/pdf.js @@ -2286,6 +2286,7 @@ var CanvasGraphics = (function() { var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); fontName = fontDescriptor.get("FontName").name; + fontName = fontName.replace("+", ""); // no + are allowed in the font name font = new Type1Font(fontName, fontFile); } break; @@ -2295,7 +2296,6 @@ var CanvasGraphics = (function() { break; case "TrueType": - break; var fontDescriptor = font.get("FontDescriptor"); if (fontDescriptor.num) { var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); From 066e4c45e0dd027dbb832e9e7178e2544f0f1bda Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 05:19:43 +0200 Subject: [PATCH 31/77] Remove the Type2 validation data from the tree --- t2data.js | 60 ------------------------------------------------------- test.html | 1 - 2 files changed, 61 deletions(-) delete mode 100644 t2data.js diff --git a/t2data.js b/t2data.js deleted file mode 100644 index 6e5f52344..000000000 --- a/t2data.js +++ /dev/null @@ -1,60 +0,0 @@ -var validationData = { -hyphen: ["-282","171","116","hstem","44","243","vstem","287","287","rmoveto","-243","-116","243","hlineto","endchar"], -period: ["-365","-13","20","hstem","125","156","rmoveto","-107","callsubr","endchar"], -zero: ["-13","28","645","28","hstem","24","158","136","158","vstem","250","688","rmoveto","-65","0","-66","-44","-41","-72","-32","-55","-22","-94","0","-83","rrcurveto","-206","94","-147","133","129","96","149","201","200","-97","151","-129","vhcurveto","68","-466","rmoveto","0","-59","-8","-78","-9","-27","-11","-29","-16","-14","-23","0","rrcurveto","-50","-19","59","148","hvcurveto","229","vlineto","151","19","58","48","49","20","-62","-147","vhcurveto","endchar"], -one: ["0","24","529","26","89","20","hstem","186","148","vstem","317","688","rmoveto","-252","-109","0","-26","rlineto","9","3","8","3","3","2","27","10","25","7","13","0","rrcurveto","25","11","-22","-47","hvcurveto","-385","vlineto","0","-82","-20","-17","-99","-1","rrcurveto","-24","375","24","vlineto","-91","2","-17","15","0","77","rrcurveto","570","vlineto","endchar"], -two: ["0","133","441","114","hstem","300","136","vstem","478","211","rmoveto","-24","hlineto","-29","-72","-12","-6","-102","0","rrcurveto","-151","0","162","154","rlineto","79","75","35","67","0","76","0","107","-77","76","-108","0","-50","0","-48","-20","-35","-36","-39","-39","-20","-34","-28","-75","rrcurveto","28","hlineto","31","62","37","28","54","0","44","0","33","-19","22","-36","12","-21","8","-28","0","-23","0","-44","-19","-55","-32","-49","-51","-78","-35","-42","-146","-156","rrcurveto","-23","416","vlineto","endchar"], -three: ["-14","50","571","81","hstemhm","283","146","-75","114","hintmask","58","523","rmoveto","38","61","33","23","52","0","63","0","39","-40","0","-63","0","-66","-35","-35","-95","-30","rrcurveto","-17","vlineto","83","-29","33","-17","36","-34","rrcurveto","hintmask","31","-29","18","-45","0","-48","0","-72","-38","-46","-60","0","-24","0","-19","11","-33","32","-39","39","-30","16","-30","0","rrcurveto","-38","-27","-24","-34","-54","61","-36","92","167","132","114","146","hvcurveto","0","46","-15","43","-29","35","-21","24","-17","12","-40","18","rrcurveto","hintmask","64","39","19","29","0","59","0","86","-61","51","-102","0","-99","0","-75","-50","-55","-103","rrcurveto","endchar"], -four: ["0","20","124","111","413","20","hstemhm","267","145","-143","143","hintmask","412","255","rmoveto","433","-80","vlineto","-59","-77","rlineto","-128","-167","-66","-92","-60","-95","rrcurveto","-113","248","-144","vlineto","hintmask","145","144","63","111","hlineto","-206","hmoveto","-209","0","209","297","rlineto","endchar"], -five: ["-8","61","496","127","hstem","373","78","vstem","149","549","rmoveto","278","0","43","127","-322","0","-97","-345","rlineto","95","-7","41","-6","44","-14","89","-28","53","-57","0","-66","0","-56","-44","-44","-56","0","-23","0","-27","12","-40","30","-43","32","-30","13","-26","0","rrcurveto","-36","-26","-25","-35","-53","58","-35","89","165","117","100","141","hvcurveto","0","104","-64","80","-109","31","-38","11","-31","4","-82","5","rrcurveto","endchar"], -six: ["-13","27","362","45","247","20","hstem","28","156","139","152","vstem","470","688","rmoveto","-133","-19","-62","-22","-76","-52","-112","-77","-59","-112","0","-133","rrcurveto","-173","92","-113","140","124","91","99","136","121","-73","78","-114","vhcurveto","-32","0","-22","-4","-30","-13","37","147","83","81","146","30","rrcurveto","-237","-286","rmoveto","67","23","-55","-159","-118","-12","-30","-49","hvcurveto","-23","0","-18","10","-10","19","-17","33","-10","73","0","93","0","62","6","57","7","5","8","6","14","4","14","0","rrcurveto","endchar"], -seven: ["0","20","519","137","hstem","477","676","rmoveto","-416","0","-44","-222","25","0","rlineto","19","64","24","21","55","0","rrcurveto","207","0","-200","-539","95","0","rlineto","endchar"], -eight: ["-13","32","640","29","hstemhm","28","121","-110","129","165","139","-133","119","hintmask","178","324","rmoveto","-57","-19","-23","-13","-26","-25","-29","-28","-15","-38","0","-44","rrcurveto","-102","85","-68","127","139","93","80","120","vhcurveto","0","87","-43","62","-107","68","rrcurveto","hintmask","96","34","40","41","0","64","rrcurveto","89","-76","56","-119","-135","-89","-70","-105","vhcurveto","0","-75","40","-55","99","-59","rrcurveto","120","98","rmoveto","-84","43","-46","55","0","56","rrcurveto","47","36","36","47","56","32","-45","-78","vhcurveto","0","-47","-8","-23","-33","-44","rrcurveto","hintmask","-98","-116","rmoveto","109","-73","24","-32","0","-74","rrcurveto","-67","-33","-41","-54","-61","-36","53","89","vhcurveto","0","55","11","31","40","59","rrcurveto","endchar"], -nine: ["-13","20","247","45","362","27","hstem","26","152","139","156","vstem","31","-13","rmoveto","140","20","68","25","78","59","102","77","54","107","0","127","rrcurveto","173","-92","113","-140","-125","-90","-99","-137","-118","73","-80","109","vhcurveto","38","0","26","5","27","14","-43","-152","-81","-79","-144","-29","rrcurveto","278","315","rmoveto","-1","-13","-1","-5","-3","-2","-7","-5","-19","-4","-15","0","rrcurveto","-62","-23","59","157","116","12","30","49","hvcurveto","25","0","17","-11","11","-23","15","-28","10","-70","0","-71","0","-27","-2","-32","-3","-45","rrcurveto","endchar"], -colon: ["-282","-13","169","147","169","hstem","166","156","rmoveto","-107","callsubr","316","vmoveto","-46","-38","-38","-45","-49","36","-37","48","47","38","38","46","47","-38","38","-47","hvcurveto","endchar"], -equal: ["-45","107","88","116","88","hstem","537","399","rmoveto","-504","-88","504","hlineto","-116","vmoveto","-504","-88","504","hlineto","endchar"], -A: ["107","0","25","172","39","223","20","191","20","hstem","689","25","rmoveto","-4","hlineto","-39","0","-16","21","-50","118","rrcurveto","-223","526","-28","0","-222","-548","rlineto","-38","-93","-12","-15","-48","-9","rrcurveto","-25","203","25","vlineto","-59","4","-23","11","0","26","0","13","8","25","21","54","rrcurveto","15","39","225","0","rlineto","34","-78","12","-36","0","-22","0","-21","-13","-10","-35","-2","-5","0","-13","-1","-14","-2","rrcurveto","-25","324","vlineto","-500","236","rmoveto","94","243","101","-243","rlineto","endchar"], -B: ["52","0","25","-25","32","614","30","-25","25","hstemhm","104","160","156","165","-138","172","hintmask","16","676","rmoveto","hintmask","-25","vlineto","69","-4","19","-16","0","-51","rrcurveto","-484","vlineto","0","-51","-15","-12","-73","-8","rrcurveto","hintmask","-25","322","vlineto","169","112","75","113","hvcurveto","0","45","-19","41","-35","31","-35","30","-34","15","-70","15","rrcurveto","hintmask","116","34","43","41","0","76","rrcurveto","103","-93","57","-167","vhcurveto","-61","-333","rmoveto","30","hlineto","hintmask","103","50","-54","-110","-97","-41","-50","-81","-44","-17","17","44","hvcurveto","504","vmoveto","36","15","13","39","vhcurveto","hintmask","70","32","-43","-94","hvcurveto","0","-105","-33","-28","-123","-3","rrcurveto","endchar"], -C: ["107","-19","48","629","33","hstem","49","177","vstem","657","152","rmoveto","-59","-62","-32","-24","-49","-19","-29","-12","-33","-6","-28","0","-66","0","-63","35","-29","52","-29","53","-14","72","0","100","0","207","64","110","120","0","47","0","43","-18","43","-38","rrcurveto","43","-39","23","-33","35","-76","rrcurveto","25","234","-27","hlineto","-14","-35","-11","-11","-19","0","-9","0","-15","4","-22","10","-59","24","-48","11","-48","0","rrcurveto","-199","-149","-154","-204","-206","147","-146","207","hvcurveto","71","0","59","17","55","37","32","22","22","20","45","50","rrcurveto","endchar"], -D: ["107","0","25","-25","35","607","34","-25","25","hstemhm","97","162","257","174","hintmask","97","91","rmoveto","0","-44","-25","-20","-58","-2","rrcurveto","hintmask","-25","316","vlineto","216","144","138","207","206","-140","125","-231","hvcurveto","-305","hlineto","hintmask","-25","vlineto","64","-6","19","-15","0","-46","rrcurveto","hintmask","162","23","rmoveto","23","20","12","39","vhcurveto","72","0","51","-33","34","-69","27","-53","14","-73","0","-84","0","-95","-20","-86","-32","-45","-34","-46","-48","-23","-65","0","rrcurveto","-45","-13","13","45","hvcurveto","endchar"], -E: ["52","0","25","-25","31","611","34","-25","25","hstemhm","104","162","hintmask","593","676","rmoveto","-577","hlineto","hintmask","-25","vlineto","69","-4","19","-16","0","-51","rrcurveto","-484","vlineto","0","-52","-14","-11","-74","-8","rrcurveto","hintmask","-25","585","vlineto","40","208","-28","0","rlineto","-31","-67","-20","-28","-36","-29","-46","-37","-55","-16","-76","0","rrcurveto","-64","-19","13","43","hvcurveto","242","vlineto","109","0","41","-39","12","-116","rrcurveto","26","338","-26","hlineto","-15","-114","-39","-36","-108","1","rrcurveto","232","vlineto","38","13","9","52","vhcurveto","163","0","49","-34","25","-133","rrcurveto","25","hlineto","endchar"], -F: ["-4","0","25","617","34","-25","25","hstemhm","104","162","hintmask","583","676","rmoveto","-567","hlineto","hintmask","-25","vlineto","69","-4","19","-15","0","-52","rrcurveto","-484","vlineto","0","-52","-14","-11","-74","-8","rrcurveto","-25","360","25","vlineto","-92","4","-18","12","0","55","rrcurveto","233","vlineto","102","-2","37","-37","14","-116","rrcurveto","25","338","-25","hlineto","-18","-114","-35","-35","-100","0","rrcurveto","232","vlineto","hintmask","37","13","10","51","vhcurveto","92","0","59","-17","31","-35","22","-25","11","-27","14","-63","rrcurveto","24","hlineto","endchar"], -G: ["163","-19","33","644","33","hstem","37","177","299","156","vstem","755","287","rmoveto","-343","-25","hlineto","86","-5","15","-11","0","-54","rrcurveto","-105","vlineto","-51","-29","-22","-67","vhcurveto","-63","0","-42","19","-33","43","-44","56","-21","86","0","120","0","209","63","111","121","0","46","0","43","-18","44","-38","43","-38","23","-34","35","-76","rrcurveto","25","234","-27","hlineto","-14","-35","-11","-11","-19","0","-9","0","-15","4","-22","10","-59","24","-48","11","-48","0","rrcurveto","-199","-149","-154","-206","-206","146","-144","210","hvcurveto","103","0","109","24","64","38","rrcurveto","127","vlineto","0","72","11","12","75","8","rrcurveto","endchar"], -I: ["-226","0","25","626","25","hstem","113","162","vstem","113","96","rmoveto","0","-50","-18","-14","-75","-7","rrcurveto","-25","350","25","vlineto","-76","5","-19","14","0","52","rrcurveto","484","vlineto","0","52","21","16","74","3","rrcurveto","25","-350","-25","vlineto","72","-5","21","-15","0","-51","rrcurveto","endchar"], -J: ["-96","33","714","25","hstem","3","116","109","162","vstem","390","559","rmoveto","0","72","14","15","75","5","rrcurveto","25","-352","-25","vlineto","81","-3","20","-14","0","-54","rrcurveto","-556","vlineto","-62","-19","-25","-45","-27","-18","13","19","vhcurveto","0","8","3","6","9","12","12","15","3","8","0","15","rrcurveto","40","-34","35","-39","-37","-33","-34","-38","vhcurveto","0","-41","28","-45","39","-23","26","-14","40","-9","40","0","rrcurveto","140","74","76","143","hvcurveto","endchar"], -L: ["52","0","25","-25","31","620","25","hstemhm","105","162","hintmask","638","227","rmoveto","-29","hlineto","-33","-78","-20","-31","-35","-32","-41","-37","-56","-18","-77","0","rrcurveto","-61","-19","13","43","hvcurveto","472","vlineto","0","75","14","13","87","4","rrcurveto","25","-349","-25","vlineto","68","-4","18","-16","0","-51","rrcurveto","-484","vlineto","hintmask","0","-51","-13","-11","-73","-9","rrcurveto","hintmask","-25","578","vlineto","endchar"], -M: ["329","0","25","626","25","hstem","105","42","531","155","vstem","678","609","rmoveto","-509","vlineto","0","-56","-14","-12","-75","-7","rrcurveto","-25","332","25","vlineto","-78","10","-10","11","0","71","rrcurveto","442","vlineto","0","72","15","15","73","5","rrcurveto","25","-252","vlineto","-200","-472","-200","472","-253","0","0","-25","rlineto","73","-6","16","-13","0","-52","rrcurveto","-475","vlineto","0","-60","-13","-12","-78","-8","rrcurveto","-25","234","25","vlineto","-82","6","-19","19","0","74","rrcurveto","0","470","252","-594","27","0","rlineto","endchar"], -N: ["107","-18","20","-2","25","626","25","hstemhm","104","44","431","44","hintmask","230","676","rmoveto","-211","-25","hlineto","20","0","17","-15","48","-57","rrcurveto","-474","vlineto","0","-57","-15","-14","-73","-9","rrcurveto","-25","227","25","vlineto","-77","9","-18","19","0","71","rrcurveto","0","402","rlineto","hintmask","447","-544","28","0","0","589","rlineto","0","57","13","13","65","10","rrcurveto","25","-215","-25","vlineto","74","-7","19","-21","0","-71","rrcurveto","-305","vlineto","endchar"], -O: ["163","-19","33","644","33","hstem","35","177","354","177","vstem","393","691","rmoveto","-209","-149","-148","-208","-207","147","-147","207","207","147","148","207","204","-149","151","-201","hvcurveto","-1","-33","rmoveto","110","64","-121","-208","-205","-62","-110","-115","-115","-62","110","202","216","63","116","117","hvcurveto","endchar"], -P: ["-4","0","25","616","35","-25","25","hstemhm","100","162","166","172","hintmask","262","303","rmoveto","135","1","34","3","44","18","81","31","44","61","0","77","rrcurveto","116","-95","66","-167","vhcurveto","-322","hlineto","hintmask","-25","vlineto","70","-6","14","-16","0","-70","rrcurveto","-442","vlineto","0","-62","-13","-20","-47","-6","-3","0","-10","-2","-11","-2","rrcurveto","-25","334","25","vlineto","-79","10","-9","9","0","73","rrcurveto","hintmask","489","vmoveto","23","17","12","33","83","33","-44","-108","vhcurveto","0","-63","-12","-38","-26","-23","-24","-20","-33","-7","-71","0","rrcurveto","endchar"], -R: ["107","0","25","617","34","-25","25","hstemhm","114","162","183","171","hintmask","715","25","rmoveto","-18","0","-13","6","-10","13","rrcurveto","-201","285","rlineto","59","19","25","13","28","25","29","27","16","40","0","45","rrcurveto","115","-99","63","-183","vhcurveto","-322","hlineto","hintmask","-25","vlineto","74","-5","14","-15","0","-72","rrcurveto","-442","vlineto","0","-73","-10","-10","-78","-9","rrcurveto","-25","338","25","vlineto","-78","10","-10","11","0","71","rrcurveto","196","27","vlineto","207","-313","205","0","rlineto","hintmask","-439","600","rmoveto","0","6","4","15","3","6","6","10","16","5","25","0","92","0","37","-43","0","-105","0","-64","-15","-39","-32","-21","-26","-17","-34","-7","-76","-1","rrcurveto","endchar"], -S: ["-59","-19","33","646","31","-19","20","hstemhm","44","109","241","119","hintmask","484","475","rmoveto","217","-30","vlineto","-7","-26","-8","-8","-17","0","-9","0","-11","3","-22","8","rrcurveto","hintmask","-47","16","-32","6","-38","0","-136","0","-83","-77","0","-126","0","-88","52","-63","119","-57","rrcurveto","67","-32","rlineto","88","-42","24","-26","0","-52","0","-69","-49","-45","-77","0","-58","0","-50","25","-38","49","-27","37","-14","33","-17","70","rrcurveto","-29","-247","29","hlineto","6","25","8","9","16","0","8","0","11","-3","22","-7","50","-17","37","-7","43","0","148","0","100","85","0","126","0","75","-46","75","-64","32","rrcurveto","-147","73","rlineto","-81","40","-22","25","0","48","0","62","42","38","68","0","45","0","42","-19","36","-37","34","-35","16","-29","20","-65","rrcurveto","endchar"], -T: ["52","0","25","631","20","hstem","253","162","vstem","253","117","rmoveto","0","-74","-11","-11","-86","-7","rrcurveto","-25","357","25","vlineto","-87","6","-11","10","0","76","rrcurveto","527","vlineto","123","-4","52","-46","17","-119","rrcurveto","29","0","-2","201","-600","0","-3","-201","29","0","rlineto","17","119","52","46","124","4","rrcurveto","endchar"], -V: ["107","-18","20","654","20","hstem","701","676","rmoveto","-213","-25","hlineto","71","-5","15","-7","0","-32","0","-16","-3","-12","-17","-43","rrcurveto","-127","-329","-138","334","rlineto","-19","45","-4","12","0","15","0","23","15","11","38","2","5","0","13","1","15","1","rrcurveto","25","-336","-25","vlineto","50","-7","9","-8","25","-55","rrcurveto","256","-599","27","0","228","587","rlineto","24","62","14","13","52","7","rrcurveto","endchar"], -W: ["385","-15","20","437","20","194","20","hstem","981","676","rmoveto","-182","-25","hlineto","54","-3","15","-10","0","-31","0","-13","-2","-15","-5","-14","rrcurveto","-112","-343","-108","336","rlineto","-10","32","-4","15","0","9","0","24","15","9","44","3","2","0","5","0","6","1","rrcurveto","25","-312","-25","vlineto","41","-2","20","-9","11","-24","rrcurveto","35","-96","-118","-308","-120","364","rlineto","-5","16","-2","8","0","9","0","29","12","9","52","4","rrcurveto","25","-294","-25","vlineto","42","-6","10","-9","17","-49","rrcurveto","212","-602","28","0","186","477","171","-477","27","0","200","602","rlineto","13","40","23","21","33","3","rrcurveto","endchar"], -a: ["-14","20","435","32","hstemhm","25","146","122","138","-137","137","hintmask","473","64","rmoveto","-10","-10","rlineto","-3","-3","-3","-1","-5","0","rrcurveto","-14","-7","9","16","hvcurveto","261","vlineto","84","-76","53","-122","-113","-76","-51","-75","-41","24","-25","41","40","28","24","34","vhcurveto","0","14","-6","13","-12","16","-9","10","-3","6","0","6","rrcurveto","21","28","16","35","vhcurveto","hintmask","58","26","-27","-61","hvcurveto","-73","vlineto","-119","-36","-49","-20","-37","-25","-43","-30","-21","-34","0","-43","0","-61","47","-45","64","0","57","0","46","20","55","50","11","-51","22","-19","49","0","43","0","31","16","38","41","rrcurveto","hintmask","-195","57","rmoveto","-27","-31","-20","-12","-24","0","-30","0","-21","27","0","40","0","58","42","42","80","21","rrcurveto","endchar"], -b: ["-59","-14","32","401","54","179","24","hstem","72","139","163","147","vstem","211","676","rmoveto","-194","-24","hlineto","46","-9","9","-9","0","-40","rrcurveto","-607","12","vlineto","79","56","rlineto","46","-41","36","-16","50","0","rrcurveto","133","93","104","149","138","-77","96","-111","hvcurveto","-48","0","-37","-17","-37","-39","rrcurveto","-57","vmoveto","17","43","20","16","33","0","rrcurveto","62","31","-67","-131","-138","-30","-65","-64","-42","-27","31","48","hvcurveto","endchar"], -c: ["-171","-14","67","389","31","hstem","25","141","vstem","412","109","rmoveto","-37","-42","-26","-14","-41","0","rrcurveto","-87","-55","87","136","103","32","63","52","hvcurveto","16","0","15","-8","6","-11","5","-9","0","0","0","-42","1","-49","18","-23","37","0","rrcurveto","42","26","24","39","62","-67","48","-88","-136","-100","-106","-144","-138","90","-99","124","hvcurveto","77","0","56","31","58","74","rrcurveto","endchar"], -d: ["-59","-14","56","-22","23","374","56","179","24","hstemhm","25","148","163","139","hintmask","339","-13","rmoveto","46","13","25","5","62","7","rrcurveto","62","8","0","23","rlineto","-46","3","-13","13","0","42","rrcurveto","575","-215","-24","vlineto","67","-5","9","-7","0","-46","rrcurveto","-183","vlineto","-43","46","-30","16","-46","0","rrcurveto","-110","-82","-107","-145","hvcurveto","hintmask","-136","76","-99","105","vhcurveto","53","0","33","16","47","50","rrcurveto","-3","60","rmoveto","0","-6","-10","-17","-12","-13","-20","-23","-21","-11","-22","0","rrcurveto","-53","-25","60","127","129","27","59","58","hvcurveto","33","0","31","-24","14","-38","rrcurveto","endchar"], -e: ["-171","-14","72","187","37","160","31","hstem","402","125","rmoveto","-40","-49","-31","-18","-43","0","-39","0","-29","18","-21","35","-18","32","-8","33","-4","69","rrcurveto","252","hlineto","-6","84","-15","47","-32","38","-33","39","-46","20","-55","0","rrcurveto","-125","-84","-99","-146","-146","82","-96","124","hvcurveto","81","0","49","32","65","93","rrcurveto","-262","171","rmoveto","3","120","18","40","49","0","28","0","19","-16","8","-31","5","-19","2","-28","2","-51","rrcurveto","-15","vlineto","endchar"], -f: ["-282","0","24","393","44","199","31","hstem","71","139","vstem","71","417","rmoveto","-333","vlineto","0","-43","-11","-12","-46","-5","rrcurveto","-24","278","24","vlineto","-70","2","-12","12","0","65","rrcurveto","314","87","44","-87","122","vlineto","55","15","22","35","18","11","-7","-12","vhcurveto","0","-4","-3","-7","-6","-10","-9","-15","-4","-11","0","-10","rrcurveto","-31","26","-24","34","37","25","25","37","59","-59","41","-84","vhcurveto","-67","0","-52","-24","-27","-44","-22","-35","-7","-41","0","-86","rrcurveto","-57","-44","hlineto","endchar"], -g: ["-206","32","122","120","87","27","216","53","-9","31","hstemhm","28","88","-79","137","132","135","-37","79","hintmask","-reserved-","482","398","rmoveto","53","-130","vlineto","hintmask","-reserved-","-44","16","-28","6","-40","0","-119","0","-84","-66","0","-95","0","-34","13","-33","23","-28","22","-24","19","-13","47","-20","-79","-27","-40","-38","0","-52","0","-41","18","-18","64","-23","rrcurveto","hintmask","-11","-63","-9","-33","-25","0","-41","rrcurveto","-58","75","-34","126","166","88","52","99","77","-62","46","-102","vhcurveto","-65","hlineto","-80","-20","7","28","30","28","22","40","hvcurveto","45","-1","rlineto","47","0","25","6","34","20","rrcurveto","hintmask","-reserved-","45","26","23","41","0","53","0","40","-12","30","-28","28","rrcurveto","-77","-450","rmoveto","hintmask","-11","54","26","-17","-33","-46","-55","-26","-99","-88","-46","23","44","hvcurveto","0","21","7","11","28","23","rrcurveto","hintmask","-reserved-","89","494","rmoveto","47","19","-38","-93","-93","-19","-36","-47","-48","-18","36","93","hvcurveto","94","19","37","47","vhcurveto","endchar"], -h: ["-59","0","24","382","67","179","24","hstem","69","139","138","139","vstem","208","676","rmoveto","-192","-24","hlineto","46","-9","7","-8","0","-41","rrcurveto","-510","vlineto","0","-42","-8","-9","-45","-9","rrcurveto","-24","241","24","vlineto","-37","5","-12","15","0","37","rrcurveto","267","vlineto","0","4","7","10","10","9","22","23","24","12","23","0","rrcurveto","35","17","-27","-56","hvcurveto","-242","vlineto","0","-37","-13","-16","-34","-4","rrcurveto","-24","235","24","vlineto","-36","3","-13","15","0","42","rrcurveto","248","vlineto","86","-53","55","-82","vhcurveto","-53","0","-37","-20","-52","-58","rrcurveto","endchar"], -i: ["-337","0","24","413","24","75","155","hstemhm","60","155","-146","139","hintmask","208","461","rmoveto","-192","-24","hlineto","44","-9","9","-9","0","-41","rrcurveto","-294","vlineto","0","-41","-7","-8","-46","-11","rrcurveto","-24","239","24","vlineto","-35","5","-12","14","0","38","rrcurveto","hintmask","-70","610","rmoveto","-43","-35","-35","-42","-45","33","-33","44","44","34","33","44","hvcurveto","43","-34","35","-43","vhcurveto","endchar"], -j: ["-282","-203","31","609","24","75","155","hstemhm","108","155","-142","139","hintmask","260","461","rmoveto","-202","-24","hlineto","51","-4","12","-12","0","-43","rrcurveto","-474","vlineto","-53","-15","-23","-33","-19","-13","7","10","vhcurveto","0","5","3","7","6","10","10","16","4","11","0","10","rrcurveto","30","-27","24","-32","-37","-25","-25","-36","-59","58","-41","82","vhcurveto","69","0","53","27","28","49","19","32","8","38","0","59","rrcurveto","hintmask","-75","689","rmoveto","-43","-34","-35","-42","-45","32","-33","45","43","35","34","43","hvcurveto","43","-35","35","-43","vhcurveto","endchar"], -k: ["-59","0","24","628","24","hstem","70","139","vstem","513","461","rmoveto","-214","-23","hlineto","11","-2","10","-1","3","-1","24","-3","11","-7","0","-13","0","-9","-10","-18","-11","-11","rrcurveto","-128","-128","0","431","-187","0","0","-24","rlineto","34","-3","14","-17","0","-38","rrcurveto","-510","vlineto","0","-39","-15","-18","-33","-3","rrcurveto","-24","239","24","vlineto","-47","7","-5","6","0","47","rrcurveto","0","114","23","24","95","-134","rlineto","17","-25","7","-12","0","-8","0","-12","-14","-6","-28","-1","rrcurveto","-24","234","24","vlineto","-11","0","-5","3","-9","12","rrcurveto","-194","268","rlineto","100","105","26","18","63","8","rrcurveto","endchar"], -l: ["-337","0","24","628","24","hstem","67","139","vstem","206","676","rmoveto","-190","-24","hlineto","35","-3","16","-18","0","-37","rrcurveto","-510","vlineto","0","-37","-17","-20","-34","-3","rrcurveto","-24","239","24","vlineto","-33","1","-16","19","0","40","rrcurveto","endchar"], -m: ["218","0","24","382","67","-36","24","hstemhm","71","139","138","139","138","139","hintmask","207","461","rmoveto","-191","-24","hlineto","44","-6","11","-12","0","-41","rrcurveto","-294","vlineto","0","-41","-11","-11","-44","-8","rrcurveto","-24","240","24","vlineto","-35","5","-11","14","0","38","rrcurveto","267","vlineto","0","6","16","19","13","10","rrcurveto","hintmask","21","16","17","7","17","0","rrcurveto","39","15","-23","-60","hvcurveto","-242","vlineto","0","-41","-11","-13","-37","-3","rrcurveto","-24","234","24","vlineto","-35","4","-12","15","0","38","rrcurveto","267","vlineto","0","5","16","19","13","10","22","17","17","7","17","0","rrcurveto","38","15","-24","-59","hvcurveto","-242","vlineto","0","-42","-11","-12","-38","-3","rrcurveto","-24","238","24","vlineto","-39","2","-11","12","0","43","rrcurveto","251","vlineto","86","-53","55","-82","vhcurveto","-57","0","-38","-23","-52","-64","-30","63","-35","24","-63","0","-63","0","-46","-27","-38","-60","rrcurveto","endchar"], -n: ["-59","0","24","382","67","-36","24","hstemhm","74","139","138","139","hintmask","212","461","rmoveto","-191","-24","hlineto","44","-7","9","-10","0","-42","rrcurveto","-294","vlineto","0","-42","-8","-9","-45","-9","rrcurveto","-24","241","24","vlineto","-37","5","-12","15","0","37","rrcurveto","267","vlineto","0","4","7","10","10","9","rrcurveto","hintmask","22","23","24","12","23","0","rrcurveto","35","17","-27","-56","hvcurveto","-242","vlineto","0","-37","-13","-16","-34","-4","rrcurveto","-24","235","24","vlineto","-39","3","-10","12","0","42","rrcurveto","251","vlineto","86","-53","55","-82","vhcurveto","-60","0","-46","-28","-37","-59","rrcurveto","endchar"], -o: ["-14","31","425","31","hstem","25","147","157","147","vstem","251","473","rmoveto","-127","-99","-105","-136","-143","95","-103","131","129","96","104","139","140","-96","104","-129","hvcurveto","1","-31","rmoveto","58","19","-55","-164","-154","-20","-52","-58","-59","-20","51","146","176","18","52","62","hvcurveto","endchar"], -p: ["-59","-205","21","-21","24","-24","205","-13","55","374","57","-36","24","hstemhm","75","139","162","148","hintmask","212","461","rmoveto","-191","-24","hlineto","44","-7","10","-10","0","-42","rrcurveto","-501","vlineto","0","-41","-8","-9","-48","-8","rrcurveto","hintmask","-24","273","vlineto","hintmask","21","vlineto","-61","3","-17","20","0","67","rrcurveto","141","vlineto","48","-47","26","-13","44","0","rrcurveto","112","80","104","148","139","-75","95","-111","hvcurveto","-59","0","-36","-23","-31","-58","rrcurveto","hintmask","2","-46","rmoveto","0","7","9","16","12","13","20","22","23","12","22","0","rrcurveto","52","24","-60","-131","-124","-28","-59","-57","hvcurveto","-33","0","-29","23","-15","38","rrcurveto","endchar"], -r: ["-171","0","24","413","24","-8","20","hstemhm","83","139","hintmask","218","461","rmoveto","-189","-24","hlineto","43","-6","11","-13","0","-40","rrcurveto","-294","vlineto","0","-41","-10","-11","-44","-8","rrcurveto","-24","266","24","vlineto","-61","4","-12","13","0","62","rrcurveto","189","vlineto","52","28","43","33","vhcurveto","8","0","9","-7","11","-16","19","-27","15","-9","26","0","rrcurveto","37","26","28","39","hvcurveto","hintmask","45","-34","33","-47","vhcurveto","-50","0","-38","-27","-47","-67","rrcurveto","endchar"], -s: ["-226","-14","34","420","33","hstem","27","100","138","96","vstem","340","326","rmoveto","145","-22","vlineto","-6","-15","-6","-5","-12","0","-6","0","-10","2","-16","5","-33","11","-23","4","-22","0","-91","0","-66","-62","0","-84","0","-66","41","-46","101","-43","68","-30","28","-25","0","-32","rrcurveto","-39","-30","-26","-45","vhcurveto","-70","0","-46","45","-21","87","rrcurveto","-28","-165","25","hlineto","11","21","6","7","9","0","5","0","8","-2","10","-4","27","-12","53","-11","28","0","91","0","63","62","0","90","0","71","-39","43","-99","42","-68","29","-28","25","0","34","rrcurveto","33","28","25","38","vhcurveto","26","0","27","-11","22","-21","21","-20","11","-18","15","-44","rrcurveto","endchar"], -t: ["-282","-12","71","358","44","hstem","72","139","vstem","305","461","rmoveto","-94","169","-25","hlineto","-61","-86","-40","-45","-65","-55","rrcurveto","-27","52","-324","vlineto","-65","43","-40","69","vhcurveto","67","0","40","30","41","82","rrcurveto","-25","11","rlineto","-20","-38","-16","-14","-21","0","rrcurveto","-28","-11","17","40","hvcurveto","301","94","vlineto","endchar"], -u: ["-59","-14","65","-31","23","394","24","hstemhm","65","139","138","139","hintmask","343","-13","rmoveto","43","15","24","4","65","7","rrcurveto","62","7","0","23","rlineto","-44","2","-12","13","0","43","rrcurveto","360","-201","-24","vlineto","50","-4","12","-12","0","-43","rrcurveto","-283","vlineto","hintmask","-33","-33","-21","-11","-28","0","rrcurveto","-41","-15","20","51","hvcurveto","339","-188","-24","vlineto","41","-8","8","-9","0","-42","rrcurveto","-252","vlineto","-88","50","-52","83","vhcurveto","52","0","35","16","58","50","rrcurveto","endchar"], -v: ["-14","20","435","20","hstem","485","461","rmoveto","-151","-24","hlineto","43","-2","12","-7","0","-24","0","-11","-4","-16","-7","-18","rrcurveto","-72","-182","-79","203","rlineto","-7","19","-2","6","0","6","0","15","10","7","25","2","2","0","8","1","8","1","rrcurveto","24","-250","-24","vlineto","23","-3","6","-3","6","-9","2","1","47","-100","16","-41","rrcurveto","120","-296","26","0","160","396","rlineto","19","44","8","8","31","3","rrcurveto","endchar"], -w: ["107","-14","20","435","20","hstem","707","461","rmoveto","-135","-24","hlineto","37","-4","11","-8","0","-23","0","-12","-13","-37","-31","-79","-15","-39","-8","-21","-12","-34","-10","41","-3","12","-21","74","-20","69","-7","28","0","9","0","16","10","5","38","3","rrcurveto","24","-234","-24","vlineto","39","-4","1","-1","19","-66","rrcurveto","6","-19","-68","-171","-24","64","rlineto","-9","21","-7","19","-5","14","-28","70","-11","32","0","13","0","16","10","8","28","4","rrcurveto","24","-222","-24","vlineto","26","-5","4","-6","27","-66","rrcurveto","148","-374","24","0","125","310","102","-310","23","0","155","401","rlineto","16","37","8","8","26","5","rrcurveto","endchar"], -x: ["0","20","421","20","hstem","484","24","rmoveto","-16","5","-7","4","-7","11","rrcurveto","-148","228","101","126","rlineto","19","23","20","11","31","5","rrcurveto","24","-168","-24","vlineto","9","-1","8","-1","3","0","23","-1","8","-6","0","-15","0","-15","-10","-17","-28","-32","-6","-6","-15","-19","-15","-21","-6","7","-4","6","-3","4","-32","42","-26","43","0","13","rrcurveto","0","12","14","6","33","1","rrcurveto","24","-250","-24","vlineto","26","-4","6","-5","20","-30","rrcurveto","128","-197","rlineto","-29","-37","-27","-33","-9","-14","-56","-74","-20","-17","-37","-2","rrcurveto","-24","169","24","vlineto","-36","2","-14","7","0","15","0","15","26","42","38","46","2","3","7","8","7","9","rrcurveto","42","-63","rlineto","23","-33","10","-19","0","-12","0","-12","-14","-6","-31","-2","rrcurveto","-24","241","vlineto","endchar"], -y: ["-205","57","589","20","hstem","16","119","vstem","480","461","rmoveto","-151","-24","hlineto","43","-2","12","-7","0","-24","0","-11","-2","-9","-9","-25","rrcurveto","-68","-192","-72","185","rlineto","-20","51","0","0","0","8","0","14","12","9","25","2","rrcurveto","16","1","0","24","-250","0","0","-24","rlineto","23","-3","6","-3","6","-9","3","0","45","-98","17","-42","rrcurveto","120","-295","-18","-53","rlineto","-17","-50","-26","-32","-23","0","-9","0","-8","8","0","9","0","1","0","2","1","3","1","5","1","5","0","4","rrcurveto","29","-24","20","-34","-37","-27","-26","-38","-46","40","-33","57","vhcurveto","34","0","29","12","21","21","21","23","20","40","35","94","rrcurveto","149","397","rlineto","17","42","10","10","31","3","rrcurveto","endchar"], -z: ["-171","0","32","409","20","hstem","420","160","rmoveto","-28","hlineto","-9","-32","-8","-18","-16","-21","-32","-44","-33","-13","-80","0","rrcurveto","-29","0","231","403","0","26","-371","0","-7","-142","26","0","rlineto","25","95","26","16","140","-1","rrcurveto","-234","-404","0","-25","383","0","rlineto","endchar"] -}; diff --git a/test.html b/test.html index be6887578..5d0b15403 100644 --- a/test.html +++ b/test.html @@ -6,7 +6,6 @@ - From 1f7aaf7b504208f414d21472057167d54041fb38 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 14:23:39 +0200 Subject: [PATCH 32/77] Add some code to make (the first one only...) font pass the sanitizer check --- PDFFont.js | 224 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 170 insertions(+), 54 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index fa4faabdd..d9074ff1e 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,3 +1,5 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ var kMaxFontFileSize = 100000; @@ -56,13 +58,18 @@ var Stack = function() { }; var Base64Encoder = { - encode: function(aData) { + encode: function(aFontName, aData) { var str = []; var count = aData.length; for (var i = 0; i < count; i++) str.push(aData.getChar ? aData.getChar() : String.fromCharCode(aData[i])); - return window.btoa(str.join("")); + // Add the css rule to the document + var fontData = window.btoa(str.join("")); + var url = "url(data:font/otf;base64," + fontData + ");"; + document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); + + return fontData; } }; @@ -78,12 +85,8 @@ var TrueTypeFont = function(aFontName, aFontFile) { } dump("Loading a TrueType font: " + aFontName); - var fontData = Base64Encoder.encode(aFontFile); + var fontData = Base64Encoder.encode(aFontName, aFontFile); Fonts.set(aFontName, fontData); - - // Add the css rule - var url = "url(data:font/ttf;base64," + fontData + ");"; - document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); }; var Type1Parser = function(aAsciiStream, aBinaryStream) { @@ -739,13 +742,9 @@ var Type1Font = function(aFontName, aFontFile) { var fontName = this.parser.parse(); var font = Fonts.get(fontName); var fontData = this.convertToOTF(this.convertToCFF(font), font); - fontData = Base64Encoder.encode(fontData); + fontData = Base64Encoder.encode(aFontName, fontData); Fonts.set(aFontName, fontData); - // Add the css rule - var url = "url(data:font/otf;base64," + fontData + ");"; - document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); - var end = Date.now(); log("Time to parse font is:" + (end - start)); } @@ -1082,19 +1081,9 @@ Type1Font.prototype = { return data; }, - - createOpenTypeHeader: function(aNumTables) { - // sfnt version (4 bytes) - var version = [0x4F, 0x54, 0x54, 0X4F]; - - // numTables (2 bytes) - var numTables = aNumTables; - - // searchRange (2bytes) - // XXX oh man this is dirty, there's probably something obvious to do to - // quickly get the maximum power of 2 value... + getMaxPower2: function(aNumber) { var maxPower = 0; - var value = numTables; + var value = aNumber; while (value >= 2) { value /= 2; maxPower++; @@ -1103,10 +1092,22 @@ Type1Font.prototype = { value = 2; for (var i = 1; i < maxPower; i++) value *= 2; - var searchRange = value * 16; + + return value; + }, + + createOpenTypeHeader: function(aNumTables) { + // sfnt version (4 bytes) + var version = [0x4F, 0x54, 0x54, 0X4F]; + + // numTables (2 bytes) + var numTables = aNumTables; + + // searchRange (2 bytes) + var searchRange = this.getMaxPower2(numTables) * 16; // entrySelector (2 bytes) - var entrySelector = Math.log(value) / Math.log(2); + var entrySelector = Math.log(this.getMaxPower2(numTables)) / Math.log(2); // rangeShift (2 bytes) var rangeShift = numTables * 16 - searchRange; @@ -1210,36 +1211,150 @@ Type1Font.prototype = { /** CMAP */ var charstrings = this.getOrderedCharStrings(aFont); - var cmap = [ - 0x00, 0x00, // version - 0x00, 0x01, // numTables - 0x00, 0x01, // platformID - 0x00, 0x00, // encodingID - 0x00, 0x00, 0x00, 0x0C, //offset - 0x00, 0x00, - 0x01, 0x06, - 0x00, 0x00 - ]; + if (false) { + var cmap = [ + 0x00, 0x00, // version + 0x00, 0x01, // numTables + 0x00, 0x01, // platformID + 0x00, 0x00, // encodingID + 0x00, 0x00, 0x00, 0x0C, //offset + 0x00, 0x00, + 0x01, 0x06, + 0x00, 0x00 + ]; - var data = []; - for (var i = 0; i < 262; i++) { - data.push(0x00); + var data = []; + for (var i = 0; i < 262; i++) { + data.push(0x00); + } + + for (var i = 0; i < charstrings.length; i++) { + var glyph = charstrings[i].glyph; + if (glyph == ".notdef") + continue; + + var pos = GlyphsUnicode[glyph]; + if (!pos) + error(charstrings[i].glyph + " does not have an entry in the glyphs table"); + var b1 = parseInt("0x" + pos[0] + pos[1]); + var b2 = parseInt("0x" + pos[2] + pos[3]); + var num = this.bytesToInteger([b1, b2]); + data[num] = i + 1; + } + cmap = cmap.concat(data); } + else { + var data = new Array(1000); + for (var i = 0; i < charstrings.length; i++) { + var glyph = charstrings[i].glyph; + if (glyph == ".notdef") + continue; - for (var i = 0; i < charstrings.length; i++) { - var glyph = charstrings[i].glyph; - if (glyph == ".notdef") - continue; + var pos = GlyphsUnicode[glyph]; + if (!pos) + error(charstrings[i].glyph + " does not have an entry in the glyphs table"); + var b1 = parseInt("0x" + pos[0] + pos[1]); + var b2 = parseInt("0x" + pos[2] + pos[3]); + var num = this.bytesToInteger([b1, b2]); + data[num] = i + 1; + } - var pos = GlyphsUnicode[glyph]; - if (!pos) - error(charstrings[i].glyph + " does not have an entry in the glyphs table"); - var b1 = parseInt("0x" + pos[0] + pos[1]); - var b2 = parseInt("0x" + pos[2] + pos[3]); - var num = this.bytesToInteger([b1, b2]); - data[num] = i + 1; + var ranges = []; + var range = []; + for (var i = 0; i < data.length; i++) { + var char = data[i]; + if (char) { + range.push(i); + } else if (range.length) { + //log("create a new range of " + range.length + " chars width min: " + range[0] + " to max: " + range[range.length - 1]); + ranges.push(range.slice()); + range = []; + } + } + + + var cmap = []; + var segCount = ranges.length + 1; + + var segCount2 = segCount * 2; + var searchRange = this.getMaxPower2(segCount) * 2; + var searchEntry = Math.log(segCount) / Math.log(2); + var rangeShift = 2 * segCount - searchRange; + cmap = cmap.concat(this.integerToBytes(segCount2, 2)); + cmap = cmap.concat(this.integerToBytes(searchRange, 2)); + cmap = cmap.concat(this.integerToBytes(searchEntry, 2)); + cmap = cmap.concat(this.integerToBytes(rangeShift, 2)); + + // End characters code with an additional 0xFFFF to finish the array + var endCodes = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + cmap = cmap.concat(this.integerToBytes(range[range.length - 1], 2)); + }; + cmap = cmap.concat([0xFF, 0xFF]); + + // reserved pad + cmap = cmap.concat([0x00, 0x00]); + + // Start characters code with an additional 0xFFFF to finish the array + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + cmap = cmap.concat(this.integerToBytes(range[0], 2)); + }; + cmap = cmap.concat([0xFF, 0xFF]); + + + // Fill idDelta + var idDelta = []; + var delta = 0; + var p = 1; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var start = range[0]; + var end = range[range.length - 1]; + var diff = end - start; + var delta = -(start - p); + + var value = this.integerToBytes(-delta, 2); + value[0] ^= 0xFF; + value[1] ^= 0xFF; + value[1] += 1; + + cmap = cmap.concat([value[0], value[1]]); + delta -= range.length; + p += range.length; + }; + cmap = cmap.concat([0x00, 0x01]); + + + // Fill id Offsets with 0x00 + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + cmap = cmap.concat([0x00, 0x00]); + }; + cmap = cmap.concat([0x00, 0x00]); + + + var cmapHeader = [ + 0x00, 0x00, // version + 0x00, 0x01, // numTables + 0x00, 0x03, // platformID + 0x00, 0x01, // encodingID + 0x00, 0x00, 0x00, 0x0C, // start of the table record + 0x00, 0x04 // format + ]; + cmapHeader = cmapHeader.concat(this.integerToBytes(cmap.length + 6, 2)); // length + cmapHeader = cmapHeader.concat(0x00, 0x00); // language + + // Fill up data! + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + for (var j = 0; j < range.length; j++) { + cmap = cmap.concat(range[j]); + } + }; + cmap = cmapHeader.concat(cmap); } - cmap = cmap.concat(data); var tableEntry = this.createTableEntry("cmap", virtualOffset, cmap); otf.set(tableEntry, currentOffset); @@ -1321,7 +1436,7 @@ Type1Font.prototype = { var maxp = [ 0x00, 0x00, 0x50, 0x00, // Version number - ].concat(this.integerToBytes(charstrings.length, 2)); // Num of glyphs + ].concat(this.integerToBytes(charstrings.length + 1, 2)); // Num of glyphs (+1 to pass the sanitizer...) var tableEntry = this.createTableEntry("maxp", virtualOffset, maxp); otf.set(tableEntry, currentOffset); @@ -1344,12 +1459,13 @@ Type1Font.prototype = { /** POST */ + // XXX get those info from the Font dict! var post = [ 0x00, 0x03, 0x00, 0x00, // Version number 0x00, 0x00, 0x01, 0x00, // italicAngle 0x00, 0x00, // underlinePosition 0x00, 0x00, // underlineThickness - 0x00, 0x00, 0x00, 0x01, // isFixedPitch + 0x00, 0x00, 0x00, 0x00, // isFixedPitch 0x00, 0x00, 0x00, 0x00, // minMemType42 0x00, 0x00, 0x00, 0x00, // maxMemType42 0x00, 0x00, 0x00, 0x00, // minMemType1 @@ -1375,7 +1491,7 @@ Type1Font.prototype = { for (var i = 0; i < currentOffset; i++) fontData.push(otf[i]); - //writeToFile(data, "/tmp/pdf.js.otf"); + writeToFile(fontData, "/tmp/pdf.js.otf"); return fontData; } }; From 6e7e8ee64ca2921551dda35b145aa47f47a20f18 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 21:53:39 +0200 Subject: [PATCH 33/77] OTF fonts works with the sanitizer (woot) --- PDFFont.js | 85 ++++++++++++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index d9074ff1e..468b86ba1 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -721,7 +721,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }; -var type1hack = false; +var fontCount = 0; var Type1Font = function(aFontName, aFontFile) { if (_Fonts[aFontName]) return; @@ -731,8 +731,8 @@ var Type1Font = function(aFontName, aFontFile) { if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); - if (!type1hack || true) { - type1hack = true; + if (!fontCount || true) { + fontCount++; var start = Date.now(); var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); @@ -851,17 +851,27 @@ Type1Font.prototype = { var dict = aFont.get("CharStrings") var charstrings = []; for (var glyph in dict.map) { + var unicode = GlyphsUnicode[glyph]; + if (!unicode) { + if (glyph != ".notdef") + warn(glyph + " does not have an entry in the glyphs unicode dictionary"); + continue; + } + + var b1 = parseInt("0x" + unicode[0] + unicode[1]); + var b2 = parseInt("0x" + unicode[2] + unicode[3]); + unicode = this.bytesToInteger([b1, b2]); + charstrings.push({ glyph: glyph, + unicode: unicode, charstring: dict.map[glyph].slice() }); } charstrings.sort(function(a, b) { - return CFFStrings.indexOf(a.glyph) > CFFStrings.indexOf(b.glyph); + return a.unicode > b.unicode; }); - charstrings.shift(); - return charstrings; }, @@ -1071,14 +1081,14 @@ Type1Font.prototype = { //var parser = new Type2Parser(); //parser.parse(new Stream(file)); - var data = []; + var fontData = []; for (var i = 0; i < currentOffset; i++) - data.push(cff[i]); + fontData.push(cff[i]); //log("== write to file"); - //writeToFile(data, "/tmp/pdf.js.cff"); + //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".cff"); - return data; + return fontData; }, getMaxPower2: function(aNumber) { @@ -1228,36 +1238,14 @@ Type1Font.prototype = { data.push(0x00); } - for (var i = 0; i < charstrings.length; i++) { - var glyph = charstrings[i].glyph; - if (glyph == ".notdef") - continue; - - var pos = GlyphsUnicode[glyph]; - if (!pos) - error(charstrings[i].glyph + " does not have an entry in the glyphs table"); - var b1 = parseInt("0x" + pos[0] + pos[1]); - var b2 = parseInt("0x" + pos[2] + pos[3]); - var num = this.bytesToInteger([b1, b2]); - data[num] = i + 1; - } + for (var i = 0; i < charstrings.length; i++) + data[charstrings[i].unicode] = i + 1; cmap = cmap.concat(data); } else { var data = new Array(1000); - for (var i = 0; i < charstrings.length; i++) { - var glyph = charstrings[i].glyph; - if (glyph == ".notdef") - continue; - - var pos = GlyphsUnicode[glyph]; - if (!pos) - error(charstrings[i].glyph + " does not have an entry in the glyphs table"); - var b1 = parseInt("0x" + pos[0] + pos[1]); - var b2 = parseInt("0x" + pos[2] + pos[3]); - var num = this.bytesToInteger([b1, b2]); - data[num] = i + 1; - } + for (var i = 0; i < charstrings.length; i++) + data[charstrings[i].unicode] = i + 1; var ranges = []; var range = []; @@ -1266,7 +1254,10 @@ Type1Font.prototype = { if (char) { range.push(i); } else if (range.length) { - //log("create a new range of " + range.length + " chars width min: " + range[0] + " to max: " + range[range.length - 1]); + if (0) { + log("create a new range of " + range.length + " chars width min: " + range[0] + " to max: " + range[range.length - 1]); + log("range content is: " + range); + } ranges.push(range.slice()); range = []; } @@ -1286,7 +1277,6 @@ Type1Font.prototype = { cmap = cmap.concat(this.integerToBytes(rangeShift, 2)); // End characters code with an additional 0xFFFF to finish the array - var endCodes = []; for (var i = 0; i < ranges.length; i++) { var range = ranges[i]; cmap = cmap.concat(this.integerToBytes(range[range.length - 1], 2)); @@ -1303,25 +1293,20 @@ Type1Font.prototype = { }; cmap = cmap.concat([0xFF, 0xFF]); - // Fill idDelta - var idDelta = []; var delta = 0; - var p = 1; + var p = 0; for (var i = 0; i < ranges.length; i++) { var range = ranges[i]; var start = range[0]; - var end = range[range.length - 1]; - var diff = end - start; - var delta = -(start - p); + var delta = ((start - 1) - p) % 65536; - var value = this.integerToBytes(-delta, 2); + var value = this.integerToBytes(delta, 2); value[0] ^= 0xFF; value[1] ^= 0xFF; value[1] += 1; - cmap = cmap.concat([value[0], value[1]]); - delta -= range.length; + p += range.length; }; cmap = cmap.concat([0x00, 0x01]); @@ -1334,7 +1319,6 @@ Type1Font.prototype = { }; cmap = cmap.concat([0x00, 0x00]); - var cmapHeader = [ 0x00, 0x00, // version 0x00, 0x01, // numTables @@ -1349,9 +1333,8 @@ Type1Font.prototype = { // Fill up data! for (var i = 0; i < ranges.length; i++) { var range = ranges[i]; - for (var j = 0; j < range.length; j++) { + for (var j = 0; j < range.length; j++) cmap = cmap.concat(range[j]); - } }; cmap = cmapHeader.concat(cmap); } @@ -1491,7 +1474,7 @@ Type1Font.prototype = { for (var i = 0; i < currentOffset; i++) fontData.push(otf[i]); - writeToFile(fontData, "/tmp/pdf.js.otf"); + //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); return fontData; } }; From 84c2e99bef768bfb7a47376ab08275dc3213aba3 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 12 Jun 2011 23:41:57 +0200 Subject: [PATCH 34/77] Add some missing glyphs --- PDFFont.js | 10 ++++++++-- glyphlist.js | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 468b86ba1..84fdf94b1 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -929,7 +929,7 @@ Type1Font.prototype = { var familyName = fontInfo.get("FamilyName"); var weight = fontInfo.get("Weight"); var strings = [version, notice, fullName, - familyName, weight]; + familyName, weight, "asteriskmath"]; var stringsIndex = this.createCFFIndexHeader(strings); var stringsDataLength = stringsIndex.length; @@ -940,6 +940,8 @@ Type1Font.prototype = { 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 = this.integerToBytes(index, 2); charset.push(bytes[0]); charset.push(bytes[1]); @@ -1103,6 +1105,10 @@ Type1Font.prototype = { for (var i = 1; i < maxPower; i++) value *= 2; + if (fontCount == 5) { + log ("mp2: " + aNumber + "::" + value); + } + return value; }, @@ -1474,7 +1480,7 @@ Type1Font.prototype = { for (var i = 0; i < currentOffset; i++) fontData.push(otf[i]); - //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); + writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); return fontData; } }; diff --git a/glyphlist.js b/glyphlist.js index de07af4a5..e147f6c8a 100644 --- a/glyphlist.js +++ b/glyphlist.js @@ -4279,5 +4279,11 @@ var GlyphsUnicode = { zretroflexhook: "0290", zstroke: "01B6", zuhiragana: "305A", - zukatakana: "30BA", + zukatakana: "30BA" }; + +// Add missing glyphs from the original Adobe's list +GlyphsUnicode["angbracketleft"] = "3008"; +GlyphsUnicode["angbracketright"] = "3009"; +GlyphsUnicode["circlecopyrt"] = "00A9"; + From 0a135091deb96caf165b51ed5bb050712f3708f9 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 01:38:05 +0200 Subject: [PATCH 35/77] Add a root 'Font' class as the outside world API --- PDFFont.js | 140 +++++++++++++++++++++++++++++++---------------------- pdf.js | 39 +++------------ 2 files changed, 91 insertions(+), 88 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 84fdf94b1..15e5f2c32 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,19 +1,86 @@ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ +/** + * 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 = {}; + + +/** + * '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, "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. + */ +var Font = function(aFontName, aFontFile, aFontType) { + this.name = aFontName; + + // If the font has already been decoded simply return + if (Fonts[aFontName]) { + this.font = Fonts[aFontName]; + return; + } + + switch (aFontType) { + case "Type1": + this.mimetype = "font/otf"; + this.font = new Type1(aFontName, aFontFile); + break; + case "TrueType": + this.mimetype = "font/ttf"; + this.font = new TrueType(aFontName, aFontFile); + break; + default: + error("Font " + aFontType + " is not supported"); + break; + } + + Fonts[aFontName] = this.font; + this.bind(); +}; + +Font.prototype = { + name: null, + font: null, + mimetype: null, + + bind: function() { + var data = this.font.data; + + // 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("")); + + // Add the @font-face rule to the document + var url = "url(data:" + this.mimetype + ";base64," + dataBase64 + ");"; + var rule = "@font-face { font-family:'" + this.name + "';src:" + url + "}"; + var styleSheet = document.styleSheets[0]; + styleSheet.insertRule(rule, styleSheet.length); + } +}; + +/** Implementation dirty logic starts here */ + var kMaxFontFileSize = 100000; /** * This dictionary holds decoded fonts data. */ -var Fonts = new Dict(); - -/** - * This simple object keep a trace of the fonts that have already been decoded - * by storing a map between the name given by the PDF and the name gather from - * the font (aka the PostScript code of the font itself for Type1 font). - */ -var _Fonts = {}; +var PSFonts = new Dict(); var Stack = function() { @@ -57,27 +124,7 @@ var Stack = function() { }; }; -var Base64Encoder = { - encode: function(aFontName, aData) { - var str = []; - var count = aData.length; - for (var i = 0; i < count; i++) - str.push(aData.getChar ? aData.getChar() : String.fromCharCode(aData[i])); - - // Add the css rule to the document - var fontData = window.btoa(str.join("")); - var url = "url(data:font/otf;base64," + fontData + ");"; - document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0); - - return fontData; - } -}; - -var TrueTypeFont = function(aFontName, aFontFile) { - if (_Fonts[aFontName]) - return; - _Fonts[aFontName] = true; - +var TrueType = function(aFontName, aFontFile) { var debug = true; function dump(aMsg) { if (debug) @@ -85,8 +132,7 @@ var TrueTypeFont = function(aFontName, aFontFile) { } dump("Loading a TrueType font: " + aFontName); - var fontData = Base64Encoder.encode(aFontName, aFontFile); - Fonts.set(aFontName, fontData); + this.data = aFontFile; }; var Type1Parser = function(aAsciiStream, aBinaryStream) { @@ -485,14 +531,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { case "def": var value = operandStack.pop(); var key = operandStack.pop(); - - // XXX we don't want to do that here but for some reasons the names - // are different between what is declared and the FontName directive - if (key == "FontName" && Fonts.get(value)) { - // The font has already be decoded, stop! - return true; - } - dump("def: " + key + " = " + value); dictionaryStack.peek().set(key, value); break; @@ -504,7 +542,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { // The key will be the identifier to recognize this font fontName = key; - Fonts.set(key, font); + PSFonts.set(key, font); operandStack.push(font); break; @@ -722,11 +760,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var fontCount = 0; -var Type1Font = function(aFontName, aFontFile) { - if (_Fonts[aFontName]) - return; - _Fonts[aFontName] = true; - +var Type1 = function(aFontName, aFontFile) { // All Type1 font program should begin with the comment %! if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) error("Invalid file header"); @@ -740,17 +774,14 @@ var Type1Font = function(aFontName, aFontFile) { this.parser = new Type1Parser(ASCIIStream, binaryStream); var fontName = this.parser.parse(); - var font = Fonts.get(fontName); - var fontData = this.convertToOTF(this.convertToCFF(font), font); - fontData = Base64Encoder.encode(aFontName, fontData); - Fonts.set(aFontName, fontData); - + var font = PSFonts.get(fontName); + this.data = this.convertToOTF(this.convertToCFF(font), font); var end = Date.now(); log("Time to parse font is:" + (end - start)); } }; -Type1Font.prototype = { +Type1.prototype = { getDefaultWidth: function(aCharstrings) { var defaultWidth = 0; var defaultUsedCount = 0; @@ -1104,11 +1135,6 @@ Type1Font.prototype = { value = 2; for (var i = 1; i < maxPower; i++) value *= 2; - - if (fontCount == 5) { - log ("mp2: " + aNumber + "::" + value); - } - return value; }, @@ -1480,7 +1506,7 @@ Type1Font.prototype = { for (var i = 0; i < currentOffset; i++) fontData.push(otf[i]); - writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); + //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); return fontData; } }; diff --git a/pdf.js b/pdf.js index cdc035c28..06928ca09 100644 --- a/pdf.js +++ b/pdf.js @@ -2278,37 +2278,14 @@ var CanvasGraphics = (function() { var fontName = ""; var subtype = font.get("Subtype").name; - switch (subtype) { - case "Type1": - var fontDescriptor = font.get("FontDescriptor"); - if (fontDescriptor.num) { - // XXX fetchIfRef looks expensive - var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); - var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); - fontName = fontDescriptor.get("FontName").name; - fontName = fontName.replace("+", ""); // no + are allowed in the font name - font = new Type1Font(fontName, fontFile); - } - break; - - case "Type3": - TODO("support Type3 font"); - break; - - case "TrueType": - var fontDescriptor = font.get("FontDescriptor"); - if (fontDescriptor.num) { - var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); - var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile2")); - fontName = fontDescriptor.get("FontName").name; - fontName = fontName.replace("+", ""); // no + are allowed in the font name - font = new TrueTypeFont(fontName, fontFile); - } - break; - - default: - error("Unsupported font type: " + subtype); - break; + var fontDescriptor = font.get("FontDescriptor"); + if (fontDescriptor.num) { + var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); + var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); + if (!fontFile) + fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile2")); + fontName = fontDescriptor.get("FontName").name.replace("+", " "); + new Font(fontName, fontFile, subtype); } this.current.fontSize = size; From a8ce1d24e95e73ae4862ef7ae81d69240839adc2 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 02:30:16 +0200 Subject: [PATCH 36/77] Beginning of the separatation of the Type1/CFF/OTF code --- PDFFont.js | 882 ++++++++++++++++++++++++++--------------------------- 1 file changed, 440 insertions(+), 442 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 15e5f2c32..8cddb2360 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1,6 +1,12 @@ /* -*- 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; + + /** * Hold a map of decoded fonts and of the standard fourteen Type1 fonts and * their acronyms. @@ -32,20 +38,32 @@ var Font = function(aFontName, aFontFile, aFontType) { switch (aFontType) { case "Type1": + // All Type1 font program should begin with the comment %! + if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) + error("Invalid file header"); + + var cff = new CFF(aFontName, aFontFile); this.mimetype = "font/otf"; - this.font = new Type1(aFontName, aFontFile); + + // Wrap the CFF data inside an OTF font file + this.font = this.cover(cff); break; + case "TrueType": this.mimetype = "font/ttf"; - this.font = new TrueType(aFontName, aFontFile); + var ttf = new TrueType(aFontName, aFontFile); + this.font = ttf.data; break; + default: - error("Font " + aFontType + " is not supported"); + warn("Font " + aFontType + " is not supported"); break; } - Fonts[aFontName] = this.font; + // Attach the font to the document this.bind(); + + Fonts[aFontName] = this.font; }; Font.prototype = { @@ -53,8 +71,8 @@ Font.prototype = { font: null, mimetype: null, - bind: function() { - var data = this.font.data; + bind: function font_bind() { + var data = this.font; // Compute the binary data to base 64 var str = []; @@ -70,12 +88,413 @@ Font.prototype = { var rule = "@font-face { font-family:'" + this.name + "';src:" + url + "}"; var styleSheet = document.styleSheets[0]; styleSheet.insertRule(rule, styleSheet.length); + }, + + _createOpenTypeHeader: function font_createOpenTypeHeader(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; + + return [].concat(version, + FontsUtils.integerToBytes(numTables, 2), + FontsUtils.integerToBytes(searchRange, 2), + FontsUtils.integerToBytes(entrySelector, 2), + FontsUtils.integerToBytes(rangeShift, 2)); + }, + + _createTableEntry: function font_createTableEntry(aTag, aOffset, aData) { + // tag + var tag = [ + aTag.charCodeAt(0), + aTag.charCodeAt(1), + aTag.charCodeAt(2), + aTag.charCodeAt(3) + ]; + + // offset + var offset = aOffset; + + // 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; + + return [].concat(tag, + FontsUtils.integerToBytes(checksum, 4), + FontsUtils.integerToBytes(offset, 4), + FontsUtils.integerToBytes(length, 4)); + }, + + _createCMAPTable: function font_createCMAPTable(aGlyphs) { + var data = new Array(1000); + for (var i = 0; i < aGlyphs.length; i++) + data[aGlyphs[i].unicode] = i + 1; + + var ranges = []; + var range = []; + for (var i = 0; i < data.length; i++) { + var char = data[i]; + if (char) { + range.push(i); + } else if (range.length) { + if (0) { + log("create a new range of " + range.length + " chars width min: " + range[0] + " to max: " + range[range.length - 1]); + log("range content is: " + range); + } + ranges.push(range.slice()); + range = []; + } + } + + + var cmap = []; + 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; + cmap = cmap.concat(FontsUtils.integerToBytes(segCount2, 2)); + cmap = cmap.concat(FontsUtils.integerToBytes(searchRange, 2)); + cmap = cmap.concat(FontsUtils.integerToBytes(searchEntry, 2)); + cmap = cmap.concat(FontsUtils.integerToBytes(rangeShift, 2)); + + // End characters code with an additional 0xFFFF to finish the array + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + cmap = cmap.concat(FontsUtils.integerToBytes(range[range.length - 1], 2)); + }; + cmap = cmap.concat([0xFF, 0xFF]); + + // reserved pad + cmap = cmap.concat([0x00, 0x00]); + + // Start characters code with an additional 0xFFFF to finish the array + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + cmap = cmap.concat(FontsUtils.integerToBytes(range[0], 2)); + }; + cmap = cmap.concat([0xFF, 0xFF]); + + // Fill idDelta + var delta = 0; + var p = 0; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var start = range[0]; + var delta = ((start - 1) - p) % 65536; + + var value = FontsUtils.integerToBytes(delta, 2); + value[0] ^= 0xFF; + value[1] ^= 0xFF; + value[1] += 1; + cmap = cmap.concat([value[0], value[1]]); + + p += range.length; + }; + cmap = cmap.concat([0x00, 0x01]); + + + // Fill id Offsets with 0x00 + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + cmap = cmap.concat([0x00, 0x00]); + }; + cmap = cmap.concat([0x00, 0x00]); + + var cmapHeader = [ + 0x00, 0x00, // version + 0x00, 0x01, // numTables + 0x00, 0x03, // platformID + 0x00, 0x01, // encodingID + 0x00, 0x00, 0x00, 0x0C, // start of the table record + 0x00, 0x04 // format + ]; + cmapHeader = cmapHeader.concat(FontsUtils.integerToBytes(cmap.length + 6, 2)); // length + cmapHeader = cmapHeader.concat(0x00, 0x00); // language + + // Fill up data! + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + for (var j = 0; j < range.length; j++) + cmap = cmap.concat(range[j]); + }; + cmap = cmapHeader.concat(cmap); + return cmap; + }, + + cover: function font_cover(aFont) { + var otf = new Uint8Array(kMaxFontFileSize); + var aFontData = aFont.data; + var currentOffset = 0; + + var numTables = 9; + //var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post]; + var header = this._createOpenTypeHeader(numTables); + otf.set(header, currentOffset); + currentOffset += header.length; + + var baseOffset = numTables * (4 * 4) + currentOffset; + var virtualOffset = baseOffset; + var tableEntry = this._createTableEntry("CFF ", virtualOffset, aFontData); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += aFontData.length; + + var 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 + 0x00, 0x00, 0x00, 0x01, // ulUnicodeRange1 (Bits 0-31) + 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange2 (Bits 32-63) + 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange3 (Bits 64-95) + 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange4 (Bits 96-127) + 0x47, 0x49, 0x60, 0x20, // 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 + ]; + + var tableEntry = this._createTableEntry("OS/2", virtualOffset, OS2); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += OS2.length; + + /** CMAP */ + var charstrings = aFont.getOrderedCharStrings(aFont.font); + + var cmap = this._createCMAPTable(charstrings); + var tableEntry = this._createTableEntry("cmap", virtualOffset, cmap); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += cmap.length; + + + /** HEAD */ + + var 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 (>= 16 && <=16384) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // created + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // modified + 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 + ]; + var tableEntry = this._createTableEntry("head", virtualOffset, head); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += head.length; + + + /** HHEA */ + + var hhea = [ + 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 + ]; + hhea = hhea.concat(FontsUtils.integerToBytes(charstrings.length, 2)); // numberOfHMetrics + + var tableEntry = this._createTableEntry("hhea", virtualOffset, hhea); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += hhea.length; + + /** HMTX */ + + var 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); + } + + var tableEntry = this._createTableEntry("hmtx", virtualOffset, hmtx); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += hmtx.length; + + + /** MAXP */ + + var maxp = [ + 0x00, 0x00, 0x50, 0x00, // Version number + ].concat(FontsUtils.integerToBytes(charstrings.length + 1, 2)); // Num of glyphs (+1 to pass the sanitizer...) + + var tableEntry = this._createTableEntry("maxp", virtualOffset, maxp); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += maxp.length; + + + /** NAME */ + + var name = [ + 0x00, 0x00, // format + 0x00, 0x00, // Number of names Record + 0x00, 0x00 // Storage + ]; + var tableEntry = this._createTableEntry("name", virtualOffset, name); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += name.length; + + + /** POST */ + + // XXX get those info from the Font dict! + var 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 + ]; + var tableEntry = this._createTableEntry("post", virtualOffset, post); + otf.set(tableEntry, currentOffset); + currentOffset += tableEntry.length; + virtualOffset += post.length; + + // Set the CFF data + otf.set(aFontData, currentOffset); + currentOffset += aFontData.length; + + var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post]; + for (var i = 0; i < tables.length; i++) { + var table = tables[i]; + otf.set(table, currentOffset); + currentOffset += table.length; + } + + var fontData = []; + for (var i = 0; i < currentOffset; i++) + fontData.push(otf[i]); + + //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); + return fontData; } }; + +var FontsUtils = { + integerToBytes: function fu_integerToBytes(aValue, aBytesCount) { + var bytes = []; + for (var i = 0; i < aBytesCount; i++) + bytes[i] = 0x00; + + do { + bytes[--aBytesCount] = (aValue & 0xFF); + aValue = aValue >> 8; + } while (aBytesCount && aValue > 0); + + return bytes; + }, + + bytesToInteger: function(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; + } +}; + + /** Implementation dirty logic starts here */ -var kMaxFontFileSize = 100000; +/** + * At the moment TrueType is just a stub that does mostly nothing but in a + * (near?) future this class will rewrite the font to ensure it is well formed + * and valid in the point of view of the sanitizer. + */ +var TrueType = function(aFontName, aFontFile) { + this.data = aFontFile; +}; /** * This dictionary holds decoded fonts data. @@ -124,17 +543,6 @@ var Stack = function() { }; }; -var TrueType = function(aFontName, aFontFile) { - var debug = true; - function dump(aMsg) { - if (debug) - log(aMsg); - } - - dump("Loading a TrueType font: " + aFontName); - this.data = aFontFile; -}; - var Type1Parser = function(aAsciiStream, aBinaryStream) { var lexer = aAsciiStream ? new Lexer(aAsciiStream) : null; @@ -760,11 +1168,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var fontCount = 0; -var Type1 = function(aFontName, aFontFile) { - // All Type1 font program should begin with the comment %! - if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) - error("Invalid file header"); - +var CFF = function(aFontName, aFontFile) { if (!fontCount || true) { fontCount++; var start = Date.now(); @@ -774,14 +1178,14 @@ var Type1 = function(aFontName, aFontFile) { this.parser = new Type1Parser(ASCIIStream, binaryStream); var fontName = this.parser.parse(); - var font = PSFonts.get(fontName); - this.data = this.convertToOTF(this.convertToCFF(font), font); + this.font = PSFonts.get(fontName); + this.data = this.convertToCFF(this.font); var end = Date.now(); log("Time to parse font is:" + (end - start)); } }; -Type1.prototype = { +CFF.prototype = { getDefaultWidth: function(aCharstrings) { var defaultWidth = 0; var defaultUsedCount = 0; @@ -809,7 +1213,7 @@ Type1.prototype = { if (count ==0) return [0x00, 0x00, 0x00]; - var bytes = this.integerToBytes(count, 2); + var bytes = FontsUtils.integerToBytes(count, 2); for (var i = 0; i < bytes.length; i++) data.push(bytes[i]); @@ -821,7 +1225,7 @@ Type1.prototype = { // 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 = this.integerToBytes(relativeOffset, 4); + var bytes = FontsUtils.integerToBytes(relativeOffset, 4); for (var j = 0; j < bytes.length; j++) data.push(bytes[j]); @@ -836,42 +1240,22 @@ Type1.prototype = { return data; }, - integerToBytes: function(aValue, aBytesCount) { - var bytes = []; - for (var i = 0; i < aBytesCount; i++) - bytes[i] = 0x00; - - do { - bytes[--aBytesCount] = (aValue & 0xFF); - aValue = aValue >> 8; - } while (aBytesCount && aValue > 0); - - return bytes; - }, - - bytesToInteger: function(aBytesArray) { - var value = 0; - for (var i = 0; i < aBytesArray.length; i++) - value = (value << 8) + aBytesArray[i]; - return value; - }, - encodeNumber: function(aValue) { var x = 0; // XXX we don't really care about Type2 optimization here... if (aValue >= -32768 && aValue <= 32767) { return [ 28, - this.integerToBytes(aValue >> 8, 1), - this.integerToBytes(aValue, 1) + FontsUtils.integerToBytes(aValue >> 8, 1), + FontsUtils.integerToBytes(aValue, 1) ]; } else if (aValue >= (-2147483647-1) && aValue <= 2147483647) { return [ 0xFF, - this.integerToBytes(aValue >> 24, 1), - this.integerToBytes(aValue >> 16, 1), - this.integerToBytes(aValue >> 8, 1), - this.integerToBytes(aValue, 1) + FontsUtils.integerToBytes(aValue >> 24, 1), + FontsUtils.integerToBytes(aValue >> 16, 1), + FontsUtils.integerToBytes(aValue >> 8, 1), + FontsUtils.integerToBytes(aValue, 1) ]; } else { error("Value: " + aValue + " is not allowed"); @@ -891,7 +1275,7 @@ Type1.prototype = { var b1 = parseInt("0x" + unicode[0] + unicode[1]); var b2 = parseInt("0x" + unicode[2] + unicode[3]); - unicode = this.bytesToInteger([b1, b2]); + unicode = FontsUtils.bytesToInteger([b1, b2]); charstrings.push({ glyph: glyph, @@ -973,7 +1357,7 @@ Type1.prototype = { var index = CFFStrings.indexOf(charstrings[i].glyph); if (index == -1) index = CFFStrings.length + strings.indexOf(glyph); - var bytes = this.integerToBytes(index, 2); + var bytes = FontsUtils.integerToBytes(index, 2); charset.push(bytes[0]); charset.push(bytes[1]); } @@ -1121,392 +1505,6 @@ Type1.prototype = { //log("== write to file"); //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".cff"); - return fontData; - }, - - getMaxPower2: function(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; - }, - - createOpenTypeHeader: function(aNumTables) { - // sfnt version (4 bytes) - var version = [0x4F, 0x54, 0x54, 0X4F]; - - // numTables (2 bytes) - var numTables = aNumTables; - - // searchRange (2 bytes) - var searchRange = this.getMaxPower2(numTables) * 16; - - // entrySelector (2 bytes) - var entrySelector = Math.log(this.getMaxPower2(numTables)) / Math.log(2); - - // rangeShift (2 bytes) - var rangeShift = numTables * 16 - searchRange; - - return [].concat(version, - this.integerToBytes(numTables, 2), - this.integerToBytes(searchRange, 2), - this.integerToBytes(entrySelector, 2), - this.integerToBytes(rangeShift, 2)); - }, - - createTableEntry: function(aTag, aOffset, aData) { - // tag - var tag = [ - aTag.charCodeAt(0), - aTag.charCodeAt(1), - aTag.charCodeAt(2), - aTag.charCodeAt(3) - ]; - - // offset - var offset = aOffset; - - // length - // Per spec tables must be 4-bytes align so add some 0x00 if needed - while (aData.length & 3) - aData.push(0x00); - - var length = aData.length; - - // checksum - var checksum = this.bytesToInteger(tag) + offset + length; - - return [].concat(tag, - this.integerToBytes(checksum, 4), - this.integerToBytes(offset, 4), - this.integerToBytes(length, 4)); - }, - - convertToOTF: function(aData, aFont) { - var otf = new Uint8Array(kMaxFontFileSize); - var currentOffset = 0; - - var numTables = 9; - var header = this.createOpenTypeHeader(numTables); - otf.set(header, currentOffset); - currentOffset += header.length; - - var baseOffset = numTables * (4 * 4) + currentOffset; - var virtualOffset = baseOffset; - var tableEntry = this.createTableEntry("CFF ", virtualOffset, aData); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += aData.length; - - var 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 - 0x00, 0x00, 0x00, 0x01, // ulUnicodeRange1 (Bits 0-31) - 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange2 (Bits 32-63) - 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange3 (Bits 64-95) - 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange4 (Bits 96-127) - 0x47, 0x49, 0x60, 0x20, // 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 - ]; - - var tableEntry = this.createTableEntry("OS/2", virtualOffset, OS2); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += OS2.length; - - /** CMAP */ - var charstrings = this.getOrderedCharStrings(aFont); - - if (false) { - var cmap = [ - 0x00, 0x00, // version - 0x00, 0x01, // numTables - 0x00, 0x01, // platformID - 0x00, 0x00, // encodingID - 0x00, 0x00, 0x00, 0x0C, //offset - 0x00, 0x00, - 0x01, 0x06, - 0x00, 0x00 - ]; - - var data = []; - for (var i = 0; i < 262; i++) { - data.push(0x00); - } - - for (var i = 0; i < charstrings.length; i++) - data[charstrings[i].unicode] = i + 1; - cmap = cmap.concat(data); - } - else { - var data = new Array(1000); - for (var i = 0; i < charstrings.length; i++) - data[charstrings[i].unicode] = i + 1; - - var ranges = []; - var range = []; - for (var i = 0; i < data.length; i++) { - var char = data[i]; - if (char) { - range.push(i); - } else if (range.length) { - if (0) { - log("create a new range of " + range.length + " chars width min: " + range[0] + " to max: " + range[range.length - 1]); - log("range content is: " + range); - } - ranges.push(range.slice()); - range = []; - } - } - - - var cmap = []; - var segCount = ranges.length + 1; - - var segCount2 = segCount * 2; - var searchRange = this.getMaxPower2(segCount) * 2; - var searchEntry = Math.log(segCount) / Math.log(2); - var rangeShift = 2 * segCount - searchRange; - cmap = cmap.concat(this.integerToBytes(segCount2, 2)); - cmap = cmap.concat(this.integerToBytes(searchRange, 2)); - cmap = cmap.concat(this.integerToBytes(searchEntry, 2)); - cmap = cmap.concat(this.integerToBytes(rangeShift, 2)); - - // End characters code with an additional 0xFFFF to finish the array - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - cmap = cmap.concat(this.integerToBytes(range[range.length - 1], 2)); - }; - cmap = cmap.concat([0xFF, 0xFF]); - - // reserved pad - cmap = cmap.concat([0x00, 0x00]); - - // Start characters code with an additional 0xFFFF to finish the array - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - cmap = cmap.concat(this.integerToBytes(range[0], 2)); - }; - cmap = cmap.concat([0xFF, 0xFF]); - - // Fill idDelta - var delta = 0; - var p = 0; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - var start = range[0]; - var delta = ((start - 1) - p) % 65536; - - var value = this.integerToBytes(delta, 2); - value[0] ^= 0xFF; - value[1] ^= 0xFF; - value[1] += 1; - cmap = cmap.concat([value[0], value[1]]); - - p += range.length; - }; - cmap = cmap.concat([0x00, 0x01]); - - - // Fill id Offsets with 0x00 - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - cmap = cmap.concat([0x00, 0x00]); - }; - cmap = cmap.concat([0x00, 0x00]); - - var cmapHeader = [ - 0x00, 0x00, // version - 0x00, 0x01, // numTables - 0x00, 0x03, // platformID - 0x00, 0x01, // encodingID - 0x00, 0x00, 0x00, 0x0C, // start of the table record - 0x00, 0x04 // format - ]; - cmapHeader = cmapHeader.concat(this.integerToBytes(cmap.length + 6, 2)); // length - cmapHeader = cmapHeader.concat(0x00, 0x00); // language - - // Fill up data! - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - for (var j = 0; j < range.length; j++) - cmap = cmap.concat(range[j]); - }; - cmap = cmapHeader.concat(cmap); - } - - var tableEntry = this.createTableEntry("cmap", virtualOffset, cmap); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += cmap.length; - - - /** HEAD */ - - var 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 (>= 16 && <=16384) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // created - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // modified - 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 - ]; - var tableEntry = this.createTableEntry("head", virtualOffset, head); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += head.length; - - - /** HHEA */ - - var hhea = [ - 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 - ]; - hhea = hhea.concat(this.integerToBytes(charstrings.length, 2)); // numberOfHMetrics - - var tableEntry = this.createTableEntry("hhea", virtualOffset, hhea); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += hhea.length; - - /** HMTX */ - - var hmtx = [0x01, 0xF4, 0x00, 0x00]; - for (var i = 0; i < charstrings.length; i++) { - var charstring = charstrings[i].charstring; - var width = this.integerToBytes(charstring[1], 2); - var lsb = this.integerToBytes(charstring[0], 2); - hmtx = hmtx.concat(width, lsb); - } - - var tableEntry = this.createTableEntry("hmtx", virtualOffset, hmtx); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += hmtx.length; - - - /** MAXP */ - - var maxp = [ - 0x00, 0x00, 0x50, 0x00, // Version number - ].concat(this.integerToBytes(charstrings.length + 1, 2)); // Num of glyphs (+1 to pass the sanitizer...) - - var tableEntry = this.createTableEntry("maxp", virtualOffset, maxp); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += maxp.length; - - - /** NAME */ - - var name = [ - 0x00, 0x00, // format - 0x00, 0x00, // Number of names Record - 0x00, 0x00 // Storage - ]; - var tableEntry = this.createTableEntry("name", virtualOffset, name); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += name.length; - - - /** POST */ - - // XXX get those info from the Font dict! - var 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 - ]; - var tableEntry = this.createTableEntry("post", virtualOffset, post); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += post.length; - - // Set the CFF data - otf.set(aData, currentOffset); - currentOffset += aData.length; - - var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post]; - for (var i = 0; i < tables.length; i++) { - var table = tables[i]; - otf.set(table, currentOffset); - currentOffset += table.length; - } - - var fontData = []; - for (var i = 0; i < currentOffset; i++) - fontData.push(otf[i]); - - //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); return fontData; } }; From 65b8158c3454a7ff0720b2d8f1827316943ff585 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 03:35:56 +0200 Subject: [PATCH 37/77] CMAP creation code is now more readable --- PDFFont.js | 115 ++++++++++++++++++++++++----------------------------- 1 file changed, 52 insertions(+), 63 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 8cddb2360..479b05add 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -147,6 +147,7 @@ Font.prototype = { for (var i = 0; i < aGlyphs.length; i++) data[aGlyphs[i].unicode] = i + 1; + // Separate the glyphs into continuous range of codes, aka segment. var ranges = []; var range = []; for (var i = 0; i < data.length; i++) { @@ -164,80 +165,68 @@ Font.prototype = { } - var cmap = []; - var segCount = ranges.length + 1; + // 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; - cmap = cmap.concat(FontsUtils.integerToBytes(segCount2, 2)); - cmap = cmap.concat(FontsUtils.integerToBytes(searchRange, 2)); - cmap = cmap.concat(FontsUtils.integerToBytes(searchEntry, 2)); - cmap = cmap.concat(FontsUtils.integerToBytes(rangeShift, 2)); + 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) + ); - // End characters code with an additional 0xFFFF to finish the array - for (var i = 0; i < ranges.length; i++) { + // 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]; - cmap = cmap.concat(FontsUtils.integerToBytes(range[range.length - 1], 2)); - }; - cmap = cmap.concat([0xFF, 0xFF]); + var start = FontsUtils.integerToBytes(range[0], 2); + var end = FontsUtils.integerToBytes(range[range.length - 1], 2); - // reserved pad - cmap = cmap.concat([0x00, 0x00]); + var delta = FontsUtils.integerToBytes(((range[0] - 1) - bias) % 65536, 2); + bias += range.length; - // Start characters code with an additional 0xFFFF to finish the array - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - cmap = cmap.concat(FontsUtils.integerToBytes(range[0], 2)); - }; - cmap = cmap.concat([0xFF, 0xFF]); + // deltas are signed shorts + delta[0] ^= 0xFF; + delta[1] ^= 0xFF; + delta[1] += 1; - // Fill idDelta - var delta = 0; - var p = 0; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - var start = range[0]; - var delta = ((start - 1) - p) % 65536; + startCount.push(start[0], start[1]); + endCount.push(end[0], end[1]); + idDeltas.push(delta[0], delta[1]); + idRangeOffsets.push(0x00, 0x00); - var value = FontsUtils.integerToBytes(delta, 2); - value[0] ^= 0xFF; - value[1] ^= 0xFF; - value[1] += 1; - cmap = cmap.concat([value[0], value[1]]); - - p += range.length; - }; - cmap = cmap.concat([0x00, 0x01]); - - - // Fill id Offsets with 0x00 - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - cmap = cmap.concat([0x00, 0x00]); - }; - cmap = cmap.concat([0x00, 0x00]); - - var cmapHeader = [ - 0x00, 0x00, // version - 0x00, 0x01, // numTables - 0x00, 0x03, // platformID - 0x00, 0x01, // encodingID - 0x00, 0x00, 0x00, 0x0C, // start of the table record - 0x00, 0x04 // format - ]; - cmapHeader = cmapHeader.concat(FontsUtils.integerToBytes(cmap.length + 6, 2)); // length - cmapHeader = cmapHeader.concat(0x00, 0x00); // language - - // Fill up data! - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; for (var j = 0; j < range.length; j++) - cmap = cmap.concat(range[j]); - }; - cmap = cmapHeader.concat(cmap); - return cmap; + 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) { @@ -442,7 +431,7 @@ Font.prototype = { for (var i = 0; i < currentOffset; i++) fontData.push(otf[i]); - //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); + writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); return fontData; } }; From cebdda3f350d5898016e34fa7f786da59c3696fc Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 03:45:24 +0200 Subject: [PATCH 38/77] Clean up a bit the CMAP ranges creation loop --- PDFFont.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 479b05add..ff1d4cfc7 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -6,6 +6,11 @@ */ var kMaxFontFileSize = 40000; +/** + * Maximum number of glyphs per font. +*/ +var kMaxGlyphsCount = 1024; + /** * Hold a map of decoded fonts and of the standard fourteen Type1 fonts and @@ -143,28 +148,22 @@ Font.prototype = { }, _createCMAPTable: function font_createCMAPTable(aGlyphs) { - var data = new Array(1000); + var characters = new Array(kMaxGlyphsCount); for (var i = 0; i < aGlyphs.length; i++) - data[aGlyphs[i].unicode] = i + 1; + characters[aGlyphs[i].unicode] = i + 1; // Separate the glyphs into continuous range of codes, aka segment. var ranges = []; var range = []; - for (var i = 0; i < data.length; i++) { - var char = data[i]; - if (char) { + for (var i = 0; i < characters.length; i++) { + if (characters[i]) { range.push(i); } else if (range.length) { - if (0) { - log("create a new range of " + range.length + " chars width min: " + range[0] + " to max: " + range[range.length - 1]); - log("range content is: " + range); - } 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). From c6f5385d15a83a152b7f7f38fde235f538aa85ce Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 04:37:53 +0200 Subject: [PATCH 39/77] Clean up a bit the code to generate an OTF --- PDFFont.js | 209 +++++++++++++++++++++++++---------------------------- 1 file changed, 98 insertions(+), 111 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index ff1d4cfc7..195bca861 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -95,7 +95,7 @@ Font.prototype = { styleSheet.insertRule(rule, styleSheet.length); }, - _createOpenTypeHeader: function font_createOpenTypeHeader(aNumTables) { + _createOpenTypeHeader: function font_createOpenTypeHeader(aFile, aOffsets, aNumTables) { // sfnt version (4 bytes) var version = [0x4F, 0x54, 0x54, 0X4F]; @@ -112,14 +112,17 @@ Font.prototype = { // rangeShift (2 bytes) var rangeShift = numTables * 16 - searchRange; - return [].concat(version, - FontsUtils.integerToBytes(numTables, 2), - FontsUtils.integerToBytes(searchRange, 2), - FontsUtils.integerToBytes(entrySelector, 2), - FontsUtils.integerToBytes(rangeShift, 2)); + 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(aTag, aOffset, aData) { + _createTableEntry: function font_createTableEntry(aFile, aOffsets, aTag, aData) { // tag var tag = [ aTag.charCodeAt(0), @@ -129,7 +132,7 @@ Font.prototype = { ]; // offset - var offset = aOffset; + var offset = aOffsets.virtualOffset; // Per spec tables must be 4-bytes align so add some 0x00 if needed while (aData.length & 3) @@ -141,10 +144,13 @@ Font.prototype = { // checksum var checksum = FontsUtils.bytesToInteger(tag) + offset + length; - return [].concat(tag, - FontsUtils.integerToBytes(checksum, 4), - FontsUtils.integerToBytes(offset, 4), - FontsUtils.integerToBytes(length, 4)); + 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) { @@ -230,23 +236,39 @@ Font.prototype = { cover: function font_cover(aFont) { var otf = new Uint8Array(kMaxFontFileSize); - var aFontData = aFont.data; - var currentOffset = 0; - var numTables = 9; - //var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post]; - var header = this._createOpenTypeHeader(numTables); - otf.set(header, currentOffset); - currentOffset += header.length; + // Required Tables + var CFF = aFont.data, + OS2 = [], + cmap = [], + head = [], + hhea = [], + hmtx = [], + maxp = [], + name = [], + post = []; + var tables = [CFF, OS2, cmap, head, hhea, hmtx, maxp, name, post]; - var baseOffset = numTables * (4 * 4) + currentOffset; - var virtualOffset = baseOffset; - var tableEntry = this._createTableEntry("CFF ", virtualOffset, aFontData); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += aFontData.length; + // 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) + }; - var OS2 = [ + // 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 @@ -268,7 +290,7 @@ Font.prototype = { 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange2 (Bits 32-63) 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange3 (Bits 64-95) 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange4 (Bits 96-127) - 0x47, 0x49, 0x60, 0x20, // achVendID + 0x2A, 0x32, 0x31, 0x2A, // achVendID 0x00, 0x20, // fsSelection 0x00, 0x2D, // usFirstCharIndex 0x00, 0x7A, // usLastCharIndex @@ -285,25 +307,17 @@ Font.prototype = { 0x00, 0xCD, // usBreakChar 0x00, 0x02 // usMaxContext ]; + this._createTableEntry(otf, offsets, "OS/2", OS2); - var tableEntry = this._createTableEntry("OS/2", virtualOffset, OS2); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += OS2.length; - - /** CMAP */ + //XXX Getting charstrings here seems wrong since this is another CFF glue var charstrings = aFont.getOrderedCharStrings(aFont.font); - var cmap = this._createCMAPTable(charstrings); - var tableEntry = this._createTableEntry("cmap", virtualOffset, cmap); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += cmap.length; - + /** CMAP */ + cmap = this._createCMAPTable(charstrings); + this._createTableEntry(otf, offsets, "cmap", cmap); /** HEAD */ - - var head = [ + head = [ 0x00, 0x01, 0x00, 0x00, // Version number 0x00, 0x00, 0x50, 0x00, // fontRevision 0x00, 0x00, 0x00, 0x00, // checksumAdjustement @@ -322,84 +336,63 @@ Font.prototype = { 0x00, 0x00, // indexToLocFormat 0x00, 0x00 // glyphDataFormat ]; - var tableEntry = this._createTableEntry("head", virtualOffset, head); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += head.length; - + this._createTableEntry(otf, offsets, "head", head); /** HHEA */ - - var hhea = [ - 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 - ]; - hhea = hhea.concat(FontsUtils.integerToBytes(charstrings.length, 2)); // numberOfHMetrics - - var tableEntry = this._createTableEntry("hhea", virtualOffset, hhea); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += hhea.length; + 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 */ - - var hmtx = [0x01, 0xF4, 0x00, 0x00]; + hmtx = [0x01, 0xF4, 0x00, 0x00]; for (var i = 0; i < charstrings.length; i++) { + // XXX this can easily broke var charstring = charstrings[i].charstring; var width = FontsUtils.integerToBytes(charstring[1], 2); var lsb = FontsUtils.integerToBytes(charstring[0], 2); hmtx = hmtx.concat(width, lsb); } - - var tableEntry = this._createTableEntry("hmtx", virtualOffset, hmtx); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += hmtx.length; - + this._createTableEntry(otf, offsets, "hmtx", hmtx); /** MAXP */ - - var maxp = [ - 0x00, 0x00, 0x50, 0x00, // Version number - ].concat(FontsUtils.integerToBytes(charstrings.length + 1, 2)); // Num of glyphs (+1 to pass the sanitizer...) - - var tableEntry = this._createTableEntry("maxp", virtualOffset, maxp); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += maxp.length; - + 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 */ - - var name = [ + name = [ 0x00, 0x00, // format 0x00, 0x00, // Number of names Record - 0x00, 0x00 // Storage + 0x00, 0x00 // Storage ]; - var tableEntry = this._createTableEntry("name", virtualOffset, name); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += name.length; - + this._createTableEntry(otf, offsets, "name", name); /** POST */ - // XXX get those info from the Font dict! - var post = [ + post = [ 0x00, 0x03, 0x00, 0x00, // Version number 0x00, 0x00, 0x01, 0x00, // italicAngle 0x00, 0x00, // underlinePosition @@ -410,24 +403,18 @@ Font.prototype = { 0x00, 0x00, 0x00, 0x00, // minMemType1 0x00, 0x00, 0x00, 0x00 // maxMemType1 ]; - var tableEntry = this._createTableEntry("post", virtualOffset, post); - otf.set(tableEntry, currentOffset); - currentOffset += tableEntry.length; - virtualOffset += post.length; + this._createTableEntry(otf, offsets, "post", post); - // Set the CFF data - otf.set(aFontData, currentOffset); - currentOffset += aFontData.length; - - var tables = [OS2, cmap, head, hhea, hmtx, maxp, name, post]; + // Once all the table entry are written, this is time to 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, currentOffset); - currentOffset += table.length; + otf.set(table, offsets.currentOffset); + offsets.currentOffset += table.length; } var fontData = []; - for (var i = 0; i < currentOffset; i++) + for (var i = 0; i < offsets.currentOffset; i++) fontData.push(otf[i]); writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); From 4039e3e1e222a5ae786225799dba2a1ebad3a34d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 04:46:21 +0200 Subject: [PATCH 40/77] Clean up a bit the code to generate an OTF (again) --- PDFFont.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 195bca861..424c6721f 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -238,15 +238,15 @@ Font.prototype = { var otf = new Uint8Array(kMaxFontFileSize); // Required Tables - var CFF = aFont.data, - OS2 = [], - cmap = [], - head = [], - hhea = [], - hmtx = [], - maxp = [], - name = [], - post = []; + 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 @@ -323,9 +323,9 @@ Font.prototype = { 0x00, 0x00, 0x00, 0x00, // checksumAdjustement 0x5F, 0x0F, 0x3C, 0xF5, // magicNumber 0x00, 0x00, // Flags - 0x03, 0xE8, // unitsPerEM (>= 16 && <=16384) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // created - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // modified + 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 @@ -334,7 +334,7 @@ Font.prototype = { 0x00, 0x00, // lowestRecPPEM 0x00, 0x00, // fontDirectionHint 0x00, 0x00, // indexToLocFormat - 0x00, 0x00 // glyphDataFormat + 0x00, 0x00 // glyphDataFormat ]; this._createTableEntry(otf, offsets, "head", head); @@ -405,7 +405,7 @@ Font.prototype = { ]; this._createTableEntry(otf, offsets, "post", post); - // Once all the table entry are written, this is time to dump the data! + // 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]; From 9830b09f34ebddbe14dafcf1d4e628a43eae68c5 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 05:30:02 +0200 Subject: [PATCH 41/77] Small changes --- PDFFont.js | 14 ++++++++------ PDFFontUtils.js | 32 +++++++++++++++++--------------- cffStandardStrings.js | 1 + test.html | 1 - 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 424c6721f..7abd9aa65 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -41,6 +41,7 @@ var Font = function(aFontName, aFontFile, aFontType) { return; } + var start = Date.now(); switch (aFontType) { case "Type1": // All Type1 font program should begin with the comment %! @@ -64,6 +65,7 @@ var Font = function(aFontName, aFontFile, aFontType) { warn("Font " + aFontType + " is not supported"); break; } + var end = Date.now(); // Attach the font to the document this.bind(); @@ -417,7 +419,7 @@ Font.prototype = { for (var i = 0; i < offsets.currentOffset; i++) fontData.push(otf[i]); - writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); + //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); return fontData; } }; @@ -477,8 +479,8 @@ var TrueType = function(aFontName, aFontFile) { var PSFonts = new Dict(); -var Stack = function() { - var innerStack = []; +var Stack = function(aStackSize) { + var innerStack = new Array(aStackSize || 0); this.push = function(aOperand) { innerStack.push(aOperand); @@ -695,7 +697,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * operator returns one or more results, it does so by pushing them on the * operand stack. */ - var operandStack = new Stack(); + var operandStack = new Stack(40); // Flag indicating if the topmost operand of the operandStack is an array var operandIsArray = 0; @@ -1156,7 +1158,7 @@ var CFF = function(aFontName, aFontFile) { this.font = PSFonts.get(fontName); this.data = this.convertToCFF(this.font); var end = Date.now(); - log("Time to parse font is:" + (end - start)); + //log("Time to parse font is:" + (end - start)); } }; @@ -1392,7 +1394,7 @@ CFF.prototype = { 248, 28, 1, // Notice 248, 29, 2, // FullName 248, 30, 3, // FamilyName - 248, 31, 4, // Weight + 248, 31, 4 // Weight ]; for (var i = 0; i < fontBBox.length; i++) diff --git a/PDFFontUtils.js b/PDFFontUtils.js index 36dc2b421..072dd48f1 100644 --- a/PDFFontUtils.js +++ b/PDFFontUtils.js @@ -4,7 +4,7 @@ * * 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. + * CharString or to understand the structure of the CFF format. */ @@ -216,6 +216,14 @@ function readFontIndexData(aStream, aIsByte) { 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; @@ -340,22 +348,16 @@ var Type2Parser = function(aFilePath) { } }; - -var xhr = new XMLHttpRequest(); -xhr.open("GET", "titi.cff", false); -xhr.mozResponseType = xhr.responseType = "arraybuffer"; -xhr.expected = (document.URL.indexOf("file:") == 0) ? 0 : 200; -xhr.send(null); -var cffData = xhr.mozResponseArrayBuffer || xhr.mozResponse || - xhr.responseArrayBuffer || xhr.response; -var cff = new Type2Parser("titi.cff"); -//cff.parse(new Stream(cffData)); +/* +var cff = new Type2Parser("test.cff"); +cff.parse(); +*/ /** * Write to a file (works only on Firefox in privilege mode"); */ - function writeToFile(aBytes, aFilePath) { +function writeToFile(aBytes, aFilePath) { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var Cc = Components.classes, Ci = Components.interfaces; @@ -366,10 +368,10 @@ var cff = new Type2Parser("titi.cff"); .createInstance(Ci.nsIFileOutputStream); stream.init(file, 0x04 | 0x08 | 0x20, 0600, 0); - var bos = Cc["@mozilla.org/binaryoutputstream;1"] - .createInstance(Ci.nsIBinaryOutputStream); + var bos = Cc["@mozilla.org/binaryoutputstream;1"] + .createInstance(Ci.nsIBinaryOutputStream); bos.setOutputStream(stream); bos.writeByteArray(aBytes, aBytes.length); stream.close(); - }; +}; diff --git a/cffStandardStrings.js b/cffStandardStrings.js index 585c1157e..8977cd8f2 100644 --- a/cffStandardStrings.js +++ b/cffStandardStrings.js @@ -686,3 +686,4 @@ var CFFDictPrivateDataMap = { operand: 0 } }; + diff --git a/test.html b/test.html index 5d0b15403..6b37f222f 100644 --- a/test.html +++ b/test.html @@ -7,7 +7,6 @@ - From e0a6c8ef76f8132ed8858989548d075d18c7490d Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Sat, 21 May 2011 13:40:28 +0800 Subject: [PATCH 42/77] use const instead of var --- pdf.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pdf.js b/pdf.js index 06928ca09..37c93a4ad 100644 --- a/pdf.js +++ b/pdf.js @@ -2130,10 +2130,10 @@ var CanvasGraphics = (function() { }; } - var LINE_CAP_STYLES = [ "butt", "round", "square" ]; - var LINE_JOIN_STYLES = [ "miter", "round", "bevel" ]; - var NORMAL_CLIP = {}; - var EO_CLIP = {}; + const LINE_CAP_STYLES = [ "butt", "round", "square" ]; + const LINE_JOIN_STYLES = [ "miter", "round", "bevel" ]; + const NORMAL_CLIP = {}; + const EO_CLIP = {}; constructor.prototype = { beginDrawing: function(mediaBox) { From 83e100b0133912531166ce524bad1769e36e34ff Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Fri, 3 Jun 2011 01:57:06 +0800 Subject: [PATCH 43/77] starting position of a stream is relative to the file, not the current stream --- pdf.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/pdf.js b/pdf.js index 37c93a4ad..8d55ff2ac 100644 --- a/pdf.js +++ b/pdf.js @@ -48,26 +48,24 @@ function shadow(obj, prop, value) { } var Stream = (function() { - function constructor(arrayBuffer, dict) { + function constructor(arrayBuffer, start, length, dict) { this.bytes = new Uint8Array(arrayBuffer); - this.pos = 0; - this.start = 0; + this.start = start || 0; + this.pos = this.start; + this.length = (start + length) || arrayBuffer.byteLength; this.dict = dict; } constructor.prototype = { - get length() { - return this.bytes.length; - }, getByte: function() { var bytes = this.bytes; - if (this.pos >= bytes.length) + if (this.pos >= this.length) return -1; return bytes[this.pos++]; }, lookChar: function() { var bytes = this.bytes; - if (this.pos >= bytes.length) + if (this.pos >= this.length) return; return String.fromCharCode(bytes[this.pos]); }, @@ -89,11 +87,8 @@ var Stream = (function() { moveStart: function() { this.start = this.pos; }, - makeSubStream: function(pos, length, dict) { - var buffer = this.bytes.buffer; - if (length) - return new Stream(new Uint8Array(buffer, pos, length), dict); - return new Stream(new Uint8Array(buffer, pos), dict); + makeSubStream: function(start, length, dict) { + return new Stream(this.bytes.buffer, start, length, dict); } }; From 2c4a0aa26971ef5da62c35023acdaf08ff9cb1bc Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 07:06:51 +0200 Subject: [PATCH 44/77] Undo last patch, it broke font rendering --- pdf.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/pdf.js b/pdf.js index 8d55ff2ac..37c93a4ad 100644 --- a/pdf.js +++ b/pdf.js @@ -48,24 +48,26 @@ function shadow(obj, prop, value) { } var Stream = (function() { - function constructor(arrayBuffer, start, length, dict) { + function constructor(arrayBuffer, dict) { this.bytes = new Uint8Array(arrayBuffer); - this.start = start || 0; - this.pos = this.start; - this.length = (start + length) || arrayBuffer.byteLength; + this.pos = 0; + this.start = 0; this.dict = dict; } constructor.prototype = { + get length() { + return this.bytes.length; + }, getByte: function() { var bytes = this.bytes; - if (this.pos >= this.length) + if (this.pos >= bytes.length) return -1; return bytes[this.pos++]; }, lookChar: function() { var bytes = this.bytes; - if (this.pos >= this.length) + if (this.pos >= bytes.length) return; return String.fromCharCode(bytes[this.pos]); }, @@ -87,8 +89,11 @@ var Stream = (function() { moveStart: function() { this.start = this.pos; }, - makeSubStream: function(start, length, dict) { - return new Stream(this.bytes.buffer, start, length, dict); + makeSubStream: function(pos, length, dict) { + var buffer = this.bytes.buffer; + if (length) + return new Stream(new Uint8Array(buffer, pos, length), dict); + return new Stream(new Uint8Array(buffer, pos), dict); } }; From 2dc7bda2bc3bce77e5bc818cdb65529988606a05 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 18:59:46 +0200 Subject: [PATCH 45/77] Merge the stream handling changes with the Font code --- PDFFont.js | 36 ++++++++++++++---------------------- pdf.js | 21 ++++++++------------- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 7abd9aa65..39d27606b 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -20,7 +20,6 @@ var kMaxGlyphsCount = 1024; */ var Fonts = {}; - /** * '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). @@ -44,10 +43,6 @@ var Font = function(aFontName, aFontFile, aFontType) { var start = Date.now(); switch (aFontType) { case "Type1": - // All Type1 font program should begin with the comment %! - if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21) - error("Invalid file header"); - var cff = new CFF(aFontName, aFontFile); this.mimetype = "font/otf"; @@ -569,7 +564,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var decryptedString = []; var value = ""; - var count = aStream.length; + var count = aStream.length - aStream.start; for (var i = 0; i < count; i++) { value = aStream.getByte(); decryptedString[i] = String.fromCharCode(value ^ (r >> 8)); @@ -949,7 +944,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { // and start interpreting it in order to decode it var file = operandStack.pop(); var eexecString = decrypt(aBinaryStream, kEexecEncryptionKey, 4).join(""); - dump(eexecString); lexer = new Lexer(new StringStream(eexecString)); break; @@ -989,13 +983,12 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var file = operandStack.pop(); // Add '1' because of the space separator, this is dirty - var stream = lexer.stream.makeSubStream(lexer.stream.pos + 1, size); + var stream = lexer.stream.makeSubStream(lexer.stream.start + lexer.stream.pos + 1, size); lexer.stream.skip(size + 1); var charString = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); var charStream = new StringStream(charString); var decodedCharString = decodeCharString(charStream); - dump("decodedCharString: " + decodedCharString); operandStack.push(decodedCharString); // boolean indicating if the operation is a success or not @@ -1144,22 +1137,21 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { }; -var fontCount = 0; var CFF = function(aFontName, aFontFile) { - if (!fontCount || true) { - fontCount++; - var start = Date.now(); + var start = Date.now(); - var ASCIIStream = aFontFile.makeSubStream(0, aFontFile.dict.get("Length1"), aFontFile.dict); - var binaryStream = aFontFile.makeSubStream(aFontFile.dict.get("Length1"), aFontFile.dict.get("Length2"), aFontFile.dict); + var length1 = aFontFile.dict.get("Length1"); + var length2 = aFontFile.dict.get("Length2"); + var pos = aFontFile.pos; + var ASCIIStream = aFontFile.makeSubStream(pos, length1, aFontFile.dict); + var binaryStream = aFontFile.makeSubStream(pos + length1, length2, aFontFile.dict); - this.parser = new Type1Parser(ASCIIStream, binaryStream); - var fontName = this.parser.parse(); - this.font = PSFonts.get(fontName); - this.data = this.convertToCFF(this.font); - var end = Date.now(); - //log("Time to parse font is:" + (end - start)); - } + this.parser = new Type1Parser(ASCIIStream, binaryStream); + var fontName = this.parser.parse(); + this.font = PSFonts.get(fontName); + this.data = this.convertToCFF(this.font); + var end = Date.now(); + //log("Time to parse font is:" + (end - start)); }; CFF.prototype = { diff --git a/pdf.js b/pdf.js index 37c93a4ad..8d55ff2ac 100644 --- a/pdf.js +++ b/pdf.js @@ -48,26 +48,24 @@ function shadow(obj, prop, value) { } var Stream = (function() { - function constructor(arrayBuffer, dict) { + function constructor(arrayBuffer, start, length, dict) { this.bytes = new Uint8Array(arrayBuffer); - this.pos = 0; - this.start = 0; + this.start = start || 0; + this.pos = this.start; + this.length = (start + length) || arrayBuffer.byteLength; this.dict = dict; } constructor.prototype = { - get length() { - return this.bytes.length; - }, getByte: function() { var bytes = this.bytes; - if (this.pos >= bytes.length) + if (this.pos >= this.length) return -1; return bytes[this.pos++]; }, lookChar: function() { var bytes = this.bytes; - if (this.pos >= bytes.length) + if (this.pos >= this.length) return; return String.fromCharCode(bytes[this.pos]); }, @@ -89,11 +87,8 @@ var Stream = (function() { moveStart: function() { this.start = this.pos; }, - makeSubStream: function(pos, length, dict) { - var buffer = this.bytes.buffer; - if (length) - return new Stream(new Uint8Array(buffer, pos, length), dict); - return new Stream(new Uint8Array(buffer, pos), dict); + makeSubStream: function(start, length, dict) { + return new Stream(this.bytes.buffer, start, length, dict); } }; From b7449f3bccdbeb5b062b93c414d85daeccc0febb Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 13 Jun 2011 23:23:13 +0200 Subject: [PATCH 46/77] Do not use makeSubStream in the CFF constructor --- PDFFont.js | 6 +++--- pdf.js | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 9318fd3a1..34fb28fc4 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1142,9 +1142,9 @@ var CFF = function(aFontName, aFontFile) { var length1 = aFontFile.dict.get("Length1"); var length2 = aFontFile.dict.get("Length2"); - var pos = aFontFile.pos; - var ASCIIStream = aFontFile.makeSubStream(pos, length1, aFontFile.dict); - var binaryStream = aFontFile.makeSubStream(pos + length1, length2, aFontFile.dict); + + var ASCIIStream = new Stream(aFontFile.getBytes(length1)); + var binaryStream = new Stream(aFontFile.getBytes(length2)); this.parser = new Type1Parser(ASCIIStream, binaryStream); var fontName = this.parser.parse(); diff --git a/pdf.js b/pdf.js index a9c9bf020..8b06f5582 100644 --- a/pdf.js +++ b/pdf.js @@ -1848,7 +1848,6 @@ var CanvasGraphics = (function() { } this.current.fontSize = size; - TODO("using hard-coded font for testing"); this.ctx.font = this.current.fontSize +'px "' + fontName + '"'; }, moveText: function (x, y) { From 375b38392082f014e7a099888cb60dfc3001bbf2 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 04:35:46 +0200 Subject: [PATCH 47/77] Make the fonts decoding code works with asynchronous data url --- PDFFont.js | 104 +++++++++++++++++++++++++++++++++++++++++++++++++---- pdf.js | 15 +++++++- test.js | 61 ++++++++++++++++++++++++------- 3 files changed, 161 insertions(+), 19 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 34fb28fc4..4e81187b9 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -11,6 +11,16 @@ var kMaxFontFileSize = 40000; */ var kMaxGlyphsCount = 1024; +/** + * Maximum time to wait for a font to be loaded by @font-face + */ +var kMaxWaitForFontFace = 2000; + + /* + * 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 @@ -36,9 +46,10 @@ var Font = function(aFontName, aFontFile, aFontType) { // If the font has already been decoded simply return if (Fonts[aFontName]) { - this.font = Fonts[aFontName]; + this.font = Fonts[aFontName].data; return; } + fontCount++; var start = Date.now(); switch (aFontType) { @@ -62,10 +73,13 @@ var Font = function(aFontName, aFontFile, aFontType) { } var end = Date.now(); + Fonts[aFontName] = { + data: this.font, + loading: true + } + // Attach the font to the document this.bind(); - - Fonts[aFontName] = this.font; }; Font.prototype = { @@ -84,10 +98,90 @@ Font.prototype = { : 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; + + var canvas = document.createElement("canvas"); + var style = "position:absolute; left: " + + (debug ? (100 * fontCount) : "-200") + "px; top: -200px;"; + canvas.setAttribute("style", style); + canvas.setAttribute("width", 100); + canvas.setAttribute("heigth", 100); + document.body.appendChild(canvas); + + // Get the first character of the font + var page = pdfDocument.getPage(pageNum); + var xref = page.xref; + var resources = xref.fetchIfRef(page.resources); + var fontResource = resources.get("Font"); + var charset = ""; + for (var id in fontResource.map) { + var res = xref.fetch(fontResource.get(id)); + var descriptor = xref.fetch(res.get("FontDescriptor")); + var name = descriptor.get("FontName").toString(); + var font = Fonts[name.replace("+", "_")]; + if (font && font.loading && name == fontName.replace("_", "+")) { + charset = descriptor.get("CharSet").split("/"); + break; + } + } + + // Warn if the charset is not found, this is likely a bug! + var testCharset = charset; + if (!charset) { + warn("No charset found for: " + fontName); + } else { + // if the charset is too small make it repeat a few times + var count = 30; + while (count-- && testCharset.length <= 30) + testCharset = testCharset.concat(charset.slice()); + } + + // Get the font size canvas think it will be + var ctx = canvas.getContext("2d"); + var testString = ""; + for (var i = 0; i < testCharset.length; i++) { + var unicode = new Number("0x" + GlyphsUnicode[testCharset[i]]); + if (!unicode) + error("Unicode for " + testCharset[i] + " is has not been found in the glyphs list"); + testString += String.fromCharCode(unicode); + } + ctx.font = "20px " + fontName + ", Symbol"; + var textWidth = ctx.mozMeasureText(testString); + + if (debug) + ctx.fillText(testString, 20, 20); + + var start = Date.now(); + var interval = window.setInterval(function(self) { + ctx.font = "20px " + fontName + ", Symbol"; + + // 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, 60); + }, 150, 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:'" + this.name + "';src:" + url + "}"; + var rule = "@font-face { font-family:'" + fontName + "';src:" + url + "}"; var styleSheet = document.styleSheets[0]; styleSheet.insertRule(rule, styleSheet.length); }, @@ -473,7 +567,6 @@ var TrueType = function(aFontName, aFontFile) { */ var PSFonts = new Dict(); - var Stack = function(aStackSize) { var innerStack = new Array(aStackSize || 0); @@ -1136,7 +1229,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { } }; - var CFF = function(aFontName, aFontFile) { var start = Date.now(); diff --git a/pdf.js b/pdf.js index 8b06f5582..697e6c3ad 100644 --- a/pdf.js +++ b/pdf.js @@ -1399,6 +1399,19 @@ var Page = (function() { ? obj : null)); }, + get fonts() { + var xref = this.xref; + var fonts = []; + + var resources = xref.fetchIfRef(this.resources); + var fontResource = resources.get("Font"); + for (var id in fontResource.map) { + var res = xref.fetch(fontResource.get(id)); + var descriptor = xref.fetch(res.get("FontDescriptor")); + fonts.push(descriptor.get("FontName").toString()); + } + return shadow(this, "fonts", fonts); + }, display: function(gfx) { var xref = this.xref; var contents = xref.fetchIfRef(this.contents); @@ -1843,7 +1856,7 @@ var CanvasGraphics = (function() { var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); if (!fontFile) fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile2")); - fontName = fontDescriptor.get("FontName").name.replace("+", " "); + fontName = fontDescriptor.get("FontName").name.replace("+", "_"); new Font(fontName, fontFile, subtype); } diff --git a/test.js b/test.js index ec784ea62..bd6c812e8 100644 --- a/test.js +++ b/test.js @@ -21,7 +21,6 @@ function queryParams() { return params; } - function open(url) { document.title = url; req = new XMLHttpRequest(); @@ -54,21 +53,59 @@ function displayPage(num) { var page = pdfDocument.getPage(pageNum = num); - var t1 = Date.now(); + function display() { + 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 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.display(gfx); - var gfx = new CanvasGraphics(ctx); - page.display(gfx); + var t2 = Date.now(); + var infoDisplay = document.getElementById("info"); + infoDisplay.innerHTML = "Time to render: "+ (t1 - t0) + "/" + (t2 - t1) + " ms"; + } - var t2 = Date.now(); + // Loading a font via data uri is asynchronous, so wait for all font + // of the page to be fully loaded before loading the page + var fontsReady = true; + var fonts = page.fonts; + for (var i = 0; i < fonts.length; i++) { + var fontName = fonts[i].replace("+", "_"); + var font = Fonts[fontName]; + if (!font) { + // load the new font + var xref = page.xref; + var resources = xref.fetchIfRef(page.resources); + var fontResource = resources.get("Font"); + for (var id in fontResource.map) { + var res = xref.fetch(fontResource.get(id)); + var descriptor = xref.fetch(res.get("FontDescriptor")); + var name = descriptor.get("FontName").toString(); + if (name == fontName.replace("_", "+")) { + var subtype = res.get("Subtype").name; + var fontFile = page.xref.fetchIfRef(descriptor.get("FontFile")); + if (!fontFile) + fontFile = page.xref.fetchIfRef(descriptor.get("FontFile2")); + new Font(fontName, fontFile, subtype); + fontsReady = false; + break; + } + } + } else if (font.loading) { + fontsReady = false; + break; + } + } - var infoDisplay = document.getElementById("info"); - infoDisplay.innerHTML = "Time to render: "+ (t1 - t0) + "/" + (t2 - t1) + " ms"; + // If everything is ready do not delayed the page loading any more + if (fontsReady) + display(); + else + setTimeout(displayPage, 150, num); } function nextPage() { From f802ad05b2d9f1cd8dd81a9167eb9b87f48dba2d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 04:52:21 +0200 Subject: [PATCH 48/77] Fix an issue with the setTimeout method used for waiting for fonts to load --- test.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test.js b/test.js index bd6c812e8..8c561e8a6 100644 --- a/test.js +++ b/test.js @@ -1,7 +1,7 @@ /* -*- 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; +var pdfDocument, canvas, pageDisplay, pageNum, pageTimeout; function load() { canvas = document.getElementById("canvas"); canvas.mozOpaque = true; @@ -47,6 +47,9 @@ function gotoPage(num) { } function displayPage(num) { + if (pageNum != num) + window.clearTimeout(pageTimeout); + document.getElementById("pageNumber").value = num; var t0 = Date.now(); @@ -104,8 +107,11 @@ function displayPage(num) { // If everything is ready do not delayed the page loading any more if (fontsReady) display(); - else - setTimeout(displayPage, 150, num); + else { + // FIXME Relying on an event seems much more cleaner here instead + // of a setTimeout... + pageTimeout = window.setTimeout(displayPage, 150, num); + } } function nextPage() { From 4cae2df1e59fe7312a93be04144bc09e0407c9f2 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 11:08:08 +0200 Subject: [PATCH 49/77] Add support for ligatures, asterisks, etc. --- PDFFont.js | 69 ++++++++++++++++++++++++++++++++++-------------------- pdf.js | 8 +++---- test.html | 1 - test.js | 16 ++++++++++++- 4 files changed, 61 insertions(+), 33 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 4e81187b9..509d714fe 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -9,7 +9,7 @@ var kMaxFontFileSize = 40000; /** * Maximum number of glyphs per font. */ -var kMaxGlyphsCount = 1024; +var kMaxGlyphsCount = 65526; /** * Maximum time to wait for a font to be loaded by @font-face @@ -28,33 +28,48 @@ var fontCount = 0; * TODO Add the standard fourteen Type1 fonts list by default * http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65 */ -var Fonts = {}; +var Fonts = { + _active: null, + get active() { + return this._active; + }, + + set active(aFontName) { + this._active = this[aFontName]; + }, + + getUnicodeFor: function fonts_getUnicodeFor(aCode) { + var glyph = this._active.encoding[aCode]; + var unicode = "0x" + GlyphsUnicode[glyph]; + return 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, "Type1"); + * 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. */ -var Font = function(aFontName, aFontFile, aFontType) { - this.name = aFontName; +var Font = function(aName, aFile, aEncoding, aType) { + this.name = aName; // If the font has already been decoded simply return - if (Fonts[aFontName]) { - this.font = Fonts[aFontName].data; + if (Fonts[aName]) { + this.font = Fonts[aName].data; return; } fontCount++; var start = Date.now(); - switch (aFontType) { + switch (aType) { case "Type1": - var cff = new CFF(aFontName, aFontFile); + var cff = new CFF(aFile); this.mimetype = "font/otf"; // Wrap the CFF data inside an OTF font file @@ -63,18 +78,19 @@ var Font = function(aFontName, aFontFile, aFontType) { case "TrueType": this.mimetype = "font/ttf"; - var ttf = new TrueType(aFontName, aFontFile); + var ttf = new TrueType(aFile); this.font = ttf.data; break; default: - warn("Font " + aFontType + " is not supported"); + warn("Font " + aType + " is not supported"); break; } var end = Date.now(); - Fonts[aFontName] = { + Fonts[aName] = { data: this.font, + encoding: aEncoding, loading: true } @@ -108,11 +124,11 @@ Font.prototype = { var debug = false; var canvas = document.createElement("canvas"); - var style = "position:absolute; left: " + - (debug ? (100 * fontCount) : "-200") + "px; top: -200px;"; + var style = "position:absolute; top: " + + (debug ? (80 * fontCount) : "-200") + "px; left: 100px;"; canvas.setAttribute("style", style); canvas.setAttribute("width", 100); - canvas.setAttribute("heigth", 100); + canvas.setAttribute("heigth", 70); document.body.appendChild(canvas); // Get the first character of the font @@ -125,7 +141,7 @@ Font.prototype = { var res = xref.fetch(fontResource.get(id)); var descriptor = xref.fetch(res.get("FontDescriptor")); var name = descriptor.get("FontName").toString(); - var font = Fonts[name.replace("+", "_")]; + var font = Fonts[name.replace("+", "_")]; if (font && font.loading && name == fontName.replace("_", "+")) { charset = descriptor.get("CharSet").split("/"); break; @@ -174,7 +190,7 @@ Font.prototype = { } if (debug) - ctx.fillText(testString, 20, 60); + ctx.fillText(testString, 20, 50); }, 150, this); /** Hack end */ @@ -246,8 +262,9 @@ Font.prototype = { _createCMAPTable: function font_createCMAPTable(aGlyphs) { var characters = new Array(kMaxGlyphsCount); - for (var i = 0; i < aGlyphs.length; i++) + 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 = []; @@ -377,10 +394,10 @@ Font.prototype = { 0x01, 0x02, // yStrikeOutPosition 0x00, 0x00, // sFamilyClass 0x02, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Panose - 0x00, 0x00, 0x00, 0x01, // ulUnicodeRange1 (Bits 0-31) - 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange2 (Bits 32-63) - 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange3 (Bits 64-95) - 0x00, 0x00, 0x00, 0x00, // ulUnicodeRange4 (Bits 96-127) + 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 @@ -558,8 +575,8 @@ var FontsUtils = { * (near?) future this class will rewrite the font to ensure it is well formed * and valid in the point of view of the sanitizer. */ -var TrueType = function(aFontName, aFontFile) { - this.data = aFontFile; +var TrueType = function(aFile) { + this.data = aFile; }; /** @@ -1229,7 +1246,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { } }; -var CFF = function(aFontName, aFontFile) { +var CFF = function(aFontFile) { var start = Date.now(); var length1 = aFontFile.dict.get("Length1"); @@ -1405,7 +1422,7 @@ CFF.prototype = { var familyName = fontInfo.get("FamilyName"); var weight = fontInfo.get("Weight"); var strings = [version, notice, fullName, - familyName, weight, "asteriskmath"]; + familyName, weight]; var stringsIndex = this.createCFFIndexHeader(strings); var stringsDataLength = stringsIndex.length; diff --git a/pdf.js b/pdf.js index 697e6c3ad..1f42bd6d6 100644 --- a/pdf.js +++ b/pdf.js @@ -798,6 +798,8 @@ var Lexer = (function() { x = (x << 3) + (ch - '0'); } } + + x = Fonts.getUnicodeFor(x); str += String.fromCharCode(x); break; case '\r': @@ -1849,15 +1851,11 @@ var CanvasGraphics = (function() { return; var fontName = ""; - var subtype = font.get("Subtype").name; var fontDescriptor = font.get("FontDescriptor"); if (fontDescriptor.num) { var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); - var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile")); - if (!fontFile) - fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile2")); fontName = fontDescriptor.get("FontName").name.replace("+", "_"); - new Font(fontName, fontFile, subtype); + Fonts.active = fontName; } this.current.fontSize = size; diff --git a/test.html b/test.html index 73ba7d2db..8d649a149 100644 --- a/test.html +++ b/test.html @@ -1,5 +1,4 @@ -<<<<<<< HEAD Simple pdf.js page viewer diff --git a/test.js b/test.js index 8c561e8a6..f2fdcfdf7 100644 --- a/test.js +++ b/test.js @@ -93,7 +93,21 @@ function displayPage(num) { var fontFile = page.xref.fetchIfRef(descriptor.get("FontFile")); if (!fontFile) fontFile = page.xref.fetchIfRef(descriptor.get("FontFile2")); - new Font(fontName, fontFile, subtype); + + // Generate the custom cmap of the font + var encoding = xref.fetch(res.get("Encoding")); + var differences = encoding.get("Differences"); + var encodingMap = {}; + var index = 0; + for (var j = 0; j < differences.length; j++) { + var data = differences[j]; + if (IsNum(data)) + index = data; + else + encodingMap[index++] = data; + } + + new Font(fontName, fontFile, encodingMap, subtype); fontsReady = false; break; } From 6a6753fd5e1068684488f95d9a16e98cc3c9ee80 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 11:59:10 +0200 Subject: [PATCH 50/77] Add support for brackets around the header emails --- PDFFont.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 509d714fe..9c6c620bb 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -38,10 +38,14 @@ var Fonts = { this._active = this[aFontName]; }, - getUnicodeFor: function fonts_getUnicodeFor(aCode) { - var glyph = this._active.encoding[aCode]; - var unicode = "0x" + GlyphsUnicode[glyph]; - return unicode || aCode; + unicodeFromCode: function fonts_unicodeFromCode(aCode) { + var active = this._active; + if (!active) + return aCode; + + var difference = active.encoding[aCode]; + var unicode = GlyphsUnicode[difference]; + return unicode ? "0x" + unicode : aCode; } }; From 6364e7fad5a12ecaa280807d1f793f0118d2ec6d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 19:40:36 +0200 Subject: [PATCH 51/77] Forgot to push function calls changes to get the unicode char from a random code --- pdf.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index 1f42bd6d6..bbfa7186a 100644 --- a/pdf.js +++ b/pdf.js @@ -799,7 +799,7 @@ var Lexer = (function() { } } - x = Fonts.getUnicodeFor(x); + x = Fonts.unicodeFromCode(x); str += String.fromCharCode(x); break; case '\r': @@ -815,7 +815,8 @@ var Lexer = (function() { } break; default: - str += ch; + var unicode = Fonts.unicodeFromCode(ch.charCodeAt(0)); + str += String.fromCharCode(unicode); break; } } while (!done); From bd2e7561003e87a3a2bd4944fdb1127560c189ad Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 21:38:59 +0200 Subject: [PATCH 52/77] Add XObjects fonts to the list of page fonts and has a forEach method to the Dict class --- PDFFont.js | 13 ++++++++++++ pdf.js | 34 +++++++++++++++++++++++-------- test.js | 60 +++++++++++++++++++++++------------------------------- 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 9c6c620bb..56e93c19a 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -580,9 +580,22 @@ var FontsUtils = { * and valid in the point of view of the sanitizer. */ var TrueType = function(aFile) { + var header = this._readOpenTypeHeader(aFile); this.data = aFile; }; +TrueType.prototype = { + _readOpenTypeHeader: function(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)) + } + } +}; + /** * This dictionary holds decoded fonts data. */ diff --git a/pdf.js b/pdf.js index bbfa7186a..afcb39fff 100644 --- a/pdf.js +++ b/pdf.js @@ -563,6 +563,10 @@ 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) @@ -1404,16 +1408,30 @@ var Page = (function() { }, get fonts() { var xref = this.xref; - var fonts = []; - var resources = xref.fetchIfRef(this.resources); - var fontResource = resources.get("Font"); - for (var id in fontResource.map) { - var res = xref.fetch(fontResource.get(id)); - var descriptor = xref.fetch(res.get("FontDescriptor")); - fonts.push(descriptor.get("FontName").toString()); + var fontsDict = new Dict(); + + // Get the fonts use on the page + var fontResources = resources.get("Font"); + fontResources.forEach(function(fontKey, fontData) { + fontsDict.set(fontKey, xref.fetch(fontData)) + }); + + // Get the fonts use on xobjects of the page if any + var xobjs = xref.fetchIfRef(resources.get("XObject")); + if (xobjs) { + xobjs.forEach(function(key, xobj) { + xobj = xref.fetchIfRef(xobj); + assertWellFormed(IsStream(xobj), "XObject should be a stream"); + + var xobjFonts = xobj.dict.get("Resources").get("Font"); + xobjFonts.forEach(function(fontKey, fontData) { + fontsDict.set(fontKey, xref.fetch(fontData)) + }); + }); } - return shadow(this, "fonts", fonts); + + return shadow(this, "fonts", fontsDict); }, display: function(gfx) { var xref = this.xref; diff --git a/test.js b/test.js index f2fdcfdf7..071b2f097 100644 --- a/test.js +++ b/test.js @@ -76,47 +76,37 @@ function displayPage(num) { // of the page to be fully loaded before loading the page var fontsReady = true; var fonts = page.fonts; - for (var i = 0; i < fonts.length; i++) { - var fontName = fonts[i].replace("+", "_"); - var font = Fonts[fontName]; - if (!font) { - // load the new font - var xref = page.xref; - var resources = xref.fetchIfRef(page.resources); - var fontResource = resources.get("Font"); - for (var id in fontResource.map) { - var res = xref.fetch(fontResource.get(id)); - var descriptor = xref.fetch(res.get("FontDescriptor")); - var name = descriptor.get("FontName").toString(); - if (name == fontName.replace("_", "+")) { - var subtype = res.get("Subtype").name; - var fontFile = page.xref.fetchIfRef(descriptor.get("FontFile")); - if (!fontFile) - fontFile = page.xref.fetchIfRef(descriptor.get("FontFile2")); + var xref = page.xref; + fonts.forEach(function(fontKey, fontDict) { + var descriptor = xref.fetch(fontDict.get("FontDescriptor")); + var fontName = descriptor.get("FontName").name; + fontName = fontName.replace("+", "_"); - // Generate the custom cmap of the font - var encoding = xref.fetch(res.get("Encoding")); - var differences = encoding.get("Differences"); + // Check if the font has been loaded or is still loading + var font = Fonts[fontName]; + if (!font) { + var fontFile = xref.fetchIfRef(descriptor.get2("FontFile", "FontFile2")); + // Generate the custom cmap of the font if needed var encodingMap = {}; - var index = 0; - for (var j = 0; j < differences.length; j++) { - var data = differences[j]; - if (IsNum(data)) - index = data; - else - encodingMap[index++] = data; + if (fontDict.has("Encoding")) { + var encoding = xref.fetchIfRef(fontDict.get("Encoding")); + if (IsDict(encoding)) { + 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; + } + } } + var subtype = fontDict.get("Subtype").name; new Font(fontName, fontFile, encodingMap, subtype); - fontsReady = false; - break; - } + return fontsReady = false; + } else if (font.loading) { + return fontsReady = false; } - } else if (font.loading) { - fontsReady = false; - break; - } - } + }); // If everything is ready do not delayed the page loading any more if (fontsReady) From c8c4326ca870de68b56698433198c00ebb418e89 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 21:51:11 +0200 Subject: [PATCH 53/77] Remove direct access to the underlying map object of dict in the fonts builder --- PDFFont.js | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 56e93c19a..58c61e051 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -135,25 +135,25 @@ Font.prototype = { canvas.setAttribute("heigth", 70); document.body.appendChild(canvas); - // Get the first character of the font + // Retrieve font charset + var charset = null; var page = pdfDocument.getPage(pageNum); var xref = page.xref; - var resources = xref.fetchIfRef(page.resources); - var fontResource = resources.get("Font"); - var charset = ""; - for (var id in fontResource.map) { - var res = xref.fetch(fontResource.get(id)); - var descriptor = xref.fetch(res.get("FontDescriptor")); + + var fonts = page.fonts; + fonts.forEach(function(fontKey, fontData) { + var descriptor = xref.fetch(fontData.get("FontDescriptor")); var name = descriptor.get("FontName").toString(); var font = Fonts[name.replace("+", "_")]; if (font && font.loading && name == fontName.replace("_", "+")) { - charset = descriptor.get("CharSet").split("/"); - break; + charset = descriptor.get("CharSet"); + charset = charset ? charset.split("/") : null; + return; } - } + }); - // Warn if the charset is not found, this is likely a bug! - var testCharset = charset; + // Warn if the charset is not found, this is likely + var testCharset = charset || []; if (!charset) { warn("No charset found for: " + fontName); } else { @@ -1358,26 +1358,26 @@ CFF.prototype = { }, getOrderedCharStrings: function(aFont) { - var dict = aFont.get("CharStrings") var charstrings = []; - for (var glyph in dict.map) { + + var glyphs = aFont.get("CharStrings") + glyphs.forEach(function(glyph, glyphData) { var unicode = GlyphsUnicode[glyph]; if (!unicode) { if (glyph != ".notdef") warn(glyph + " does not have an entry in the glyphs unicode dictionary"); - continue; + } else { + var b1 = parseInt("0x" + unicode[0] + unicode[1]); + var b2 = parseInt("0x" + unicode[2] + unicode[3]); + unicode = FontsUtils.bytesToInteger([b1, b2]); + + charstrings.push({ + glyph: glyph, + unicode: unicode, + charstring: glyphData.slice() + }); } - - var b1 = parseInt("0x" + unicode[0] + unicode[1]); - var b2 = parseInt("0x" + unicode[2] + unicode[3]); - unicode = FontsUtils.bytesToInteger([b1, b2]); - - charstrings.push({ - glyph: glyph, - unicode: unicode, - charstring: dict.map[glyph].slice() - }); - } + }); charstrings.sort(function(a, b) { return a.unicode > b.unicode; From 1dcd42b66c3dd3fadcc4fca66f4d8908f26d5645 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 15 Jun 2011 04:46:48 +0200 Subject: [PATCH 54/77] Add a basic support for TrueType (generate fonts with OS/2 table) --- PDFFont.js | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++- pdf.js | 18 +++-- test.js | 4 +- 3 files changed, 246 insertions(+), 9 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 58c61e051..fd7e0d86f 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -581,11 +581,213 @@ var FontsUtils = { */ var TrueType = function(aFile) { var header = this._readOpenTypeHeader(aFile); - this.data = 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.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; + //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".ttf"); + return; + } else if (requiredTables.lenght) { + error("Table " + requiredTables[0] + " is missing from the TruType font"); + } else { + this.data = aFile; + } }; TrueType.prototype = { - _readOpenTypeHeader: function(aFile) { + _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)), @@ -593,6 +795,33 @@ TrueType.prototype = { 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 + } } }; diff --git a/pdf.js b/pdf.js index afcb39fff..f46362f7f 100644 --- a/pdf.js +++ b/pdf.js @@ -52,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; } @@ -1411,11 +1411,13 @@ var Page = (function() { var resources = xref.fetchIfRef(this.resources); var fontsDict = new Dict(); - // Get the fonts use on the page + // Get the fonts use on the page if any var fontResources = resources.get("Font"); - fontResources.forEach(function(fontKey, fontData) { - fontsDict.set(fontKey, xref.fetch(fontData)) - }); + if (IsDict(fontResources)) { + fontResources.forEach(function(fontKey, fontData) { + fontsDict.set(fontKey, xref.fetch(fontData)) + }); + } // Get the fonts use on xobjects of the page if any var xobjs = xref.fetchIfRef(resources.get("XObject")); @@ -1864,7 +1866,11 @@ var CanvasGraphics = (function() { this.current.leading = leading; }, setFont: function(fontRef, size) { - var font = this.res.get("Font").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; diff --git a/test.js b/test.js index 071b2f097..2b99dc136 100644 --- a/test.js +++ b/test.js @@ -85,7 +85,9 @@ function displayPage(num) { // Check if the font has been loaded or is still loading var font = Fonts[fontName]; if (!font) { - var fontFile = xref.fetchIfRef(descriptor.get2("FontFile", "FontFile2")); + 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")) { From f7e90f569c989fc5e317a242df3a91d68eb515a2 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 15 Jun 2011 05:40:54 +0200 Subject: [PATCH 55/77] Add Encodings.js and change the code to generate a CharSet per font, this will allow future changes to the OpenType font generator --- Encodings.js | 1552 ++++++++++++++++++++++++++++++++++++++++++++++++++ PDFFont.js | 46 +- test.html | 1 + test.js | 19 +- 4 files changed, 1584 insertions(+), 34 deletions(-) create mode 100644 Encodings.js 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/PDFFont.js b/PDFFont.js index fd7e0d86f..ff06c5e4e 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -40,7 +40,7 @@ var Fonts = { unicodeFromCode: function fonts_unicodeFromCode(aCode) { var active = this._active; - if (!active) + if (!active || !active.encoding) return aCode; var difference = active.encoding[aCode]; @@ -60,7 +60,7 @@ var Fonts = { * 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. */ -var Font = function(aName, aFile, aEncoding, aType) { +var Font = function(aName, aFile, aEncoding, aCharset, aType) { this.name = aName; // If the font has already been decoded simply return @@ -95,6 +95,7 @@ var Font = function(aName, aFile, aEncoding, aType) { Fonts[aName] = { data: this.font, encoding: aEncoding, + charset: aCharset ? aCharset.slice() : null, loading: true } @@ -125,10 +126,10 @@ Font.prototype = { // 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; + var debug = true; var canvas = document.createElement("canvas"); - var style = "position:absolute; top: " + + var style = "border: 1px solid black; position:absolute; top: " + (debug ? (80 * fontCount) : "-200") + "px; left: 100px;"; canvas.setAttribute("style", style); canvas.setAttribute("width", 100); @@ -136,40 +137,19 @@ Font.prototype = { document.body.appendChild(canvas); // Retrieve font charset - var charset = null; - var page = pdfDocument.getPage(pageNum); - var xref = page.xref; - - var fonts = page.fonts; - fonts.forEach(function(fontKey, fontData) { - var descriptor = xref.fetch(fontData.get("FontDescriptor")); - var name = descriptor.get("FontName").toString(); - var font = Fonts[name.replace("+", "_")]; - if (font && font.loading && name == fontName.replace("_", "+")) { - charset = descriptor.get("CharSet"); - charset = charset ? charset.split("/") : null; - return; - } - }); - - // Warn if the charset is not found, this is likely - var testCharset = charset || []; - if (!charset) { - warn("No charset found for: " + fontName); - } else { - // if the charset is too small make it repeat a few times - var count = 30; - while (count-- && testCharset.length <= 30) - testCharset = testCharset.concat(charset.slice()); - } + 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 var ctx = canvas.getContext("2d"); var testString = ""; - for (var i = 0; i < testCharset.length; i++) { - var unicode = new Number("0x" + GlyphsUnicode[testCharset[i]]); + for (var i = 0; i < charset.length; i++) { + var unicode = new Number("0x" + GlyphsUnicode[charset[i]]); if (!unicode) - error("Unicode for " + testCharset[i] + " is has not been found in the glyphs list"); + error("Unicode for " + charset[i] + " is has not been found in the glyphs list"); testString += String.fromCharCode(unicode); } ctx.font = "20px " + fontName + ", Symbol"; diff --git a/test.html b/test.html index 8d649a149..d18f9599b 100644 --- a/test.html +++ b/test.html @@ -7,6 +7,7 @@ + diff --git a/test.js b/test.js index 2b99dc136..1dffac549 100644 --- a/test.js +++ b/test.js @@ -93,17 +93,34 @@ function displayPage(num) { 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 subtype = fontDict.get("Subtype").name; - new Font(fontName, fontFile, encodingMap, subtype); + new Font(fontName, fontFile, encodingMap, charset, subtype); return fontsReady = false; } else if (font.loading) { return fontsReady = false; From 73350b1f46d44707ebcc8563dea0da7aa06043f3 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 15 Jun 2011 05:42:15 +0200 Subject: [PATCH 56/77] Forgot to turn off some debug flags --- PDFFont.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PDFFont.js b/PDFFont.js index ff06c5e4e..f20f7e24f 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -126,7 +126,7 @@ Font.prototype = { // 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 = true; + var debug = false; var canvas = document.createElement("canvas"); var style = "border: 1px solid black; position:absolute; top: " + From 2519e4f53b02cebbec59f4194288e4e2a7108e8a Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 15 Jun 2011 09:21:59 +0200 Subject: [PATCH 57/77] Make Type1 glyphs use the default width they declare --- PDFFont.js | 68 ++++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 48 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index f20f7e24f..89dc22d42 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1375,10 +1375,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { * as descrived in 'Using Subroutines' of 'Adobe Type 1 Font Format', * chapter 8. */ - this.flattenCharstring = function(aCharstring, aDefaultWidth, aSubrs) { + this.flattenCharstring = function(aCharstring, aSubrs) { operandStack.clear(); executionStack.clear(); - executionStack.push(aCharstring); + executionStack.push(aCharstring.slice()); var leftSidebearing = 0; var lastPoint = 0; @@ -1392,24 +1392,13 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { switch (obj) { case "hsbw": var charWidthVector = operandStack.pop(); - leftSidebearing = operandStack.pop(); - - if (charWidthVector != aDefaultWidth) - operandStack.push(charWidthVector - aDefaultWidth); - break; - - case "rmoveto": - var dy = operandStack.pop(); - var dx = operandStack.pop(); + var leftSidebearing = operandStack.pop(); + operandStack.push(charWidthVector); if (leftSidebearing) { - dx += leftSidebearing; - leftSidebearing = 0; + operandStack.push(leftSidebearing); + operandStack.push("hmoveto"); } - - operandStack.push(dx); - operandStack.push(dy); - operandStack.push("rmoveto"); break; case "div": @@ -1445,12 +1434,13 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { break; case "callothersubr": - // XXX need to be improved var index = operandStack.pop(); var count = operandStack.pop(); var data = operandStack.pop(); + // XXX The callothersubr needs to support at least the 3 defaults + // otherSubrs of the spec if (index != 3) - dump("callothersubr for index: " + index); + error("callothersubr for index: " + index); operandStack.push(3); operandStack.push("callothersubr"); break; @@ -1490,25 +1480,6 @@ var CFF = function(aFontFile) { }; CFF.prototype = { - getDefaultWidth: function(aCharstrings) { - var defaultWidth = 0; - var defaultUsedCount = 0; - - var widths = {}; - for (var i = 0; i < aCharstrings.length; i++) { - var width = aCharstrings[i].charstring[1]; - var usedCount = (widths[width] || 0) + 1; - - if (usedCount > defaultUsedCount) { - defaultUsedCount = usedCount; - defaultWidth = width; - } - - widths[width] = usedCount; - } - return parseInt(defaultWidth); - }, - createCFFIndexHeader: function(aObjects, aIsByte) { var data = []; @@ -1602,7 +1573,6 @@ CFF.prototype = { }; var charstrings = this.getOrderedCharStrings(aFont); - var defaultWidth = this.getDefaultWidth(charstrings); var charstringsCount = 0; var charstringsDataLength = 0; @@ -1617,7 +1587,7 @@ CFF.prototype = { error("glyphs already exists!"); glyphsChecker[glyph] = true; - var flattened = parser.flattenCharstring(charstring, defaultWidth, subrs); + var flattened = parser.flattenCharstring(charstring, subrs); glyphs.push(flattened); charstringsCount++; charstringsDataLength += flattened.length; @@ -1712,8 +1682,6 @@ CFF.prototype = { charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why? - var fontBBox = aFont.get("FontBBox"); - //Top Dict Index var topDictIndex = [ 0x00, 0x01, 0x01, 0x01, 0x30, @@ -1724,6 +1692,7 @@ CFF.prototype = { 248, 31, 4 // Weight ]; + var fontBBox = aFont.get("FontBBox"); for (var i = 0; i < fontBBox.length; i++) topDictIndex = topDictIndex.concat(this.encodeNumber(fontBBox[i])); topDictIndex.push(5) // FontBBox; @@ -1768,19 +1737,22 @@ CFF.prototype = { currentOffset += charstringsIndex.length; // Private Data - var privateData = [ - 248, 136, 20, - 248, 136, 21, + var defaultWidth = this.encodeNumber(0); + var privateData = [].concat( + defaultWidth, [20], + defaultWidth, [21], + [ 119, 159, 248, 97, 159, 247, 87, 159, 6, 30, 10, 3, 150, 37, 255, 12, 9, - 139, 12, 10, - 172, 10, + 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; From 650ed04a702485e209843bbfe38fc5a0faeed905 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 15 Jun 2011 23:02:30 +0200 Subject: [PATCH 58/77] Get rid of the PostScript interpreter (part 1) --- PDFFont.js | 448 ++++++++++++----------------------------------------- test.js | 4 +- 2 files changed, 105 insertions(+), 347 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 89dc22d42..e54f3ec4b 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -14,7 +14,7 @@ var kMaxGlyphsCount = 65526; /** * Maximum time to wait for a font to be loaded by @font-face */ -var kMaxWaitForFontFace = 2000; +var kMaxWaitForFontFace = 1000; /* * Useful for debugging when you want to certains operations depending on how @@ -59,8 +59,11 @@ var Fonts = { * * 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. + * + * XXX 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, aType) { +var Font = function(aName, aFile, aEncoding, aCharset, aBBox, aType) { this.name = aName; // If the font has already been decoded simply return @@ -73,7 +76,7 @@ var Font = function(aName, aFile, aEncoding, aCharset, aType) { var start = Date.now(); switch (aType) { case "Type1": - var cff = new CFF(aFile); + var cff = new CFF(aName, aBBox, aFile); this.mimetype = "font/otf"; // Wrap the CFF data inside an OTF font file @@ -175,7 +178,7 @@ Font.prototype = { if (debug) ctx.fillText(testString, 20, 50); - }, 150, this); + }, 20, this); /** Hack end */ @@ -402,7 +405,7 @@ Font.prototype = { this._createTableEntry(otf, offsets, "OS/2", OS2); //XXX Getting charstrings here seems wrong since this is another CFF glue - var charstrings = aFont.getOrderedCharStrings(aFont.font); + var charstrings = aFont.getOrderedCharStrings(aFont.glyphs); /** CMAP */ cmap = this._createCMAPTable(charstrings); @@ -851,9 +854,7 @@ var Stack = function(aStackSize) { }; }; -var Type1Parser = function(aAsciiStream, aBinaryStream) { - var lexer = aAsciiStream ? new Lexer(aAsciiStream) : null; - +var Type1Parser = function() { // Turn on this flag for additional debugging logs var debug = false; @@ -862,30 +863,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { log(aData); }; - // Hold the fontName as declared inside the /FontName postscript directive - // XXX This is a hack but at the moment I need it to map the name declared - // in the PDF and the name in the PS code. - var fontName = ""; - - /* - * Parse a whole Type1 font stream (from the first segment to the last) - * assuming the 'eexec' block is binary data and fill up the 'Fonts' - * dictionary with the font informations. - */ - var self = this; - this.parse = function() { - if (!debug) { - while (!processNextToken()) {}; - return fontName; - } else { - // debug mode is used to debug postcript processing - setTimeout(function() { - if (!processNextToken()) - self.parse(); - }, 0); - } - }; - /* * 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 @@ -894,7 +871,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var kEexecEncryptionKey = 55665; var kCharStringsEncryptionKey = 4330; - function decrypt(aStream, aKey, aDiscardNumber) { + function decrypt(aStream, aKey, aDiscardNumber, aByteArray) { var start = Date.now(); var r = aKey, c1 = 52845, c2 = 22719; var decryptedString = []; @@ -903,7 +880,10 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var count = aStream.length; for (var i = 0; i < count; i++) { value = aStream.getByte(); - decryptedString[i] = String.fromCharCode(value ^ (r >> 8)); + 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(); @@ -1017,7 +997,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { var end = Date.now(); dump("Time to decode charString of length " + count + " is " + (end - start)); return charString; - } + }; /* * The operand stack holds arbitrary PostScript objects that are the operands @@ -1068,305 +1048,76 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { */ function nextInStack() { var currentProcedure = executionStack.peek(); - if (currentProcedure) { - var command = currentProcedure.shift(); - if (!currentProcedure.length) - executionStack.pop(); - return command; - } - - return lexer.getObj(); + var command = currentProcedure.shift(); + if (!currentProcedure.length) + executionStack.pop(); + return command; }; - /* - * Get the next token from the executionStack and process it. - * Actually the function does not process the third segment of a Type1 font - * and end on 'closefile'. - * - * The method thrown an error if it encounters an unknown token. + /** + * Returns an object containing a Subrs array and a CharStrings array + * extracted from and eexec encrypted block of data */ - function processNextToken() { - var obj = nextInStack(); - if (operandIsArray && !IsCmd(obj, "{") && !IsCmd(obj, "[") && - !IsCmd(obj, "]") && !IsCmd(obj, "}")) { - dump("Adding an object: " + obj +" to array " + operandIsArray); - var currentArray = operandStack.peek(); - for (var i = 1; i < operandIsArray; i++) - currentArray = currentArray[currentArray.length - 1]; + this.extractFontInfo = function(aStream) { + var eexecString = decrypt(new Stream(aStream), kEexecEncryptionKey, 4, true); + var subrs = [], glyphs = []; + var inSubrs = inGlyphs = false; + var glyph = ""; - currentArray.push(obj); - } else if (IsBool(obj) || IsInt(obj) || IsNum(obj) || IsString(obj)) { - dump("Value: " + obj); - operandStack.push(obj); - } else if (IsName(obj)) { - dump("Name: " + obj.name); - operandStack.push(obj.name); - } else if (IsCmd(obj)) { - var command = obj.cmd; - dump(command); + var token = ""; + var index = 0; + var length = 0; - switch (command) { - case "[": - case "{": - dump("Start" + (command == "{" ? " Executable " : " ") + "Array"); - operandIsArray++; - var currentArray = operandStack; - for (var i = 1; i < operandIsArray; i++) - if (currentArray.peek) - currentArray = currentArray.peek(); - else - currentArray = currentArray[currentArray.length - 1]; - currentArray.push([]); - break; + var count = eexecString.length; + var c = ""; + for (var i = 0; i < count; i++) { + var c = eexecString[i]; - case "]": - case "}": - var currentArray = operandStack.peek(); - for (var i = 1; i < operandIsArray; i++) - currentArray = currentArray[currentArray.length - 1]; - dump("End" + (command == "}" ? " Executable " : " ") + "Array: " + currentArray.join(" ")); - operandIsArray--; - break; + if (inSubrs && c == 0x52) { + length = parseInt(length); + var stream = new Stream(eexecString.slice(i + 3, i + 3 + length)); + var encodedSubr = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); + var subr = decodeCharString(new StringStream(encodedSubr)); - case "if": - var procedure = operandStack.pop(); - var bool = operandStack.pop(); - if (!IsBool(bool)) { - dump("if: " + bool); - // we need to execute things, let be dirty - executionStack.push(bool); - } else { - dump("if ( " + bool + " ) { " + procedure + " }"); - if (bool) - executionStack.push(procedure); - } - break; + subrs.push(subr); + i += 3 + length; + } else if (inGlyphs && c == 0x52) { + length = parseInt(length); + var stream = new Stream(eexecString.slice(i + 3, i + 3 + length)); + var encodedCharstring = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); + var subr = decodeCharString(new StringStream(encodedCharstring)); - case "ifelse": - var procedure1 = operandStack.pop(); - var procedure2 = operandStack.pop(); - var bool = !!operandStack.pop(); - dump("if ( " + bool + " ) { " + procedure2 + " } else { " + procedure1 + " }"); - executionStack.push(bool ? procedure2 : procedure1); - break; + glyphs.push({ + glyph: glyph, + data: subr + }); + i += 3 + length; + } else if (inGlyphs && c == 0x2F) { + token = ""; + glyph = ""; - case "for": - var procedure = operandStack.pop(); - var limit = operandStack.pop(); - var increment = operandStack.pop(); - var initial = operandStack.pop(); - for (var i = 0; i < limit; i += increment) { - operandStack.push(i); - executionStack.push(procedure.slice()); - } - break; - - case "dup": - dump("duplicate: " + operandStack.peek()); - operandStack.push(operandStack.peek()); - break; - - case "mark": - operandStack.push("mark"); - break; - - case "cleartomark": - var command = ""; - do { - command = operandStack.pop(); - } while (command != "mark"); - break; - - case "put": - var data = operandStack.pop(); - var indexOrKey = operandStack.pop(); - var object = operandStack.pop(); - dump("put " + data + " in " + object + "[" + indexOrKey + "]"); - object.set ? object.set(indexOrKey, data) - : object[indexOrKey] = data; - break; - - case "pop": - operandStack.pop(); - break; - - case "exch": - var operand1 = operandStack.pop(); - var operand2 = operandStack.pop(); - operandStack.push(operand1); - operandStack.push(operand2); - break; - - case "get": - var indexOrKey = operandStack.pop(); - var object = operandStack.pop(); - var data = object.get ? object.get(indexOrKey) : object[indexOrKey]; - dump("get " + object + "[" + indexOrKey + "]: " + data); - operandStack.push(data); - break; - - case "currentdict": - var dict = dictionaryStack.peek(); - operandStack.push(dict); - break; - - case "systemdict": - operandStack.push(systemDict); - break; - - case "readonly": - case "executeonly": - case "noaccess": - // Do nothing for the moment - break; - - case "currentfile": - operandStack.push("currentfile"); - break; - - case "array": - var size = operandStack.pop(); - var array = new Array(size); - operandStack.push(array); - break; - - case "dict": - var size = operandStack.pop(); - var dict = new Dict(size); - operandStack.push(dict); - break; - - case "begin": - dictionaryStack.push(operandStack.pop()); - break; - - case "end": - dictionaryStack.pop(); - break; - - case "def": - var value = operandStack.pop(); - var key = operandStack.pop(); - dump("def: " + key + " = " + value); - dictionaryStack.peek().set(key, value); - break; - - case "definefont": - var font = operandStack.pop(); - var key = operandStack.pop(); - dump("definefont " + font + " with key: " + key); - - // The key will be the identifier to recognize this font - fontName = key; - PSFonts.set(key, font); - - operandStack.push(font); - break; - - case "known": - var name = operandStack.pop(); - var dict = operandStack.pop(); - var data = !!dict.get(name); - dump("known: " + data + " :: " + name + " in dict: " + dict); - operandStack.push(data); - break; - - case "exec": - executionStack.push(operandStack.pop()); - break; - - case "eexec": - // All the first segment data has been read, decrypt the second segment - // and start interpreting it in order to decode it - var file = operandStack.pop(); - var eexecString = decrypt(aBinaryStream, kEexecEncryptionKey, 4).join(""); - lexer = new Lexer(new StringStream(eexecString)); - break; - - case "LenIV": - error("LenIV: argh! we need to modify the length of discard characters for charStrings"); - break; - - case "closefile": - var file = operandStack.pop(); - return true; - break; - - case "index": - var operands = []; - var size = operandStack.pop(); - for (var i = 0; i < size; i++) - operands.push(operandStack.pop()); - - var newOperand = operandStack.peek(); - - while (operands.length) - operandStack.push(operands.pop()); - - operandStack.push(newOperand); - break; - - case "string": - var size = operandStack.pop(); - var str = (new Array(size + 1)).join(" "); - operandStack.push(str); - break; - - case "readstring": - var str = operandStack.pop(); - var size = str.length; - - var file = operandStack.pop(); - - // Add '1' because of the space separator, this is dirty - var stream = lexer.stream.makeSubStream(lexer.stream.start + lexer.stream.pos + 1, size); - lexer.stream.skip(size + 1); - - var charString = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); - var charStream = new StringStream(charString); - var decodedCharString = decodeCharString(charStream); - operandStack.push(decodedCharString); - - // boolean indicating if the operation is a success or not - operandStack.push(true); - break; - - case "StandardEncoding": - // For some reason the value is considered as a command, maybe it is - // because of the uppercase 'S' - operandStack.push(obj.cmd); - break; - - default: - var command = null; - if (IsCmd(obj)) { - for (var i = 0; i < dictionaryStack.count(); i++) { - if (command = dictionaryStack.get(i).get(obj.cmd)) { - dump("found in dictionnary for " + obj.cmd + " command: " + command); - executionStack.push(command.slice()); - break; - } - } - } - - if (!command) { - log("operandStack: " + operandStack); - log("dictionaryStack: " + dictionaryStack); - log(obj); - error("Unknow command while parsing font"); - } - break; + while ((c = eexecString[++i]) != 0x20 && i < count) + glyph += String.fromCharCode(c); + } else if (c == 0x2F && eexecString[i+1] == 0x53 && !inGlyphs && !inSubrs) { + 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); } - } else if (obj) { - dump("unknow: " + obj); - operandStack.push(obj); - } else { // The End! - operandStack.dump(); - return true; } - - return false; - } + return { + subrs: subrs, + charstrings: glyphs + } + }; /* * Flatten the commands by interpreting the postscript code and replacing @@ -1462,19 +1213,25 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) { } }; -var CFF = function(aFontFile) { +var CFF = function(aFontName, aFontBBox, aFontFile) { var start = Date.now(); + // 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); - var ASCIIStream = new Stream(aFontFile.getBytes(length1)); - var binaryStream = new Stream(aFontFile.getBytes(length2)); + // Extract informations from it + var parser = new Type1Parser(); + var fontInfo = parser.extractFontInfo(eexecBlock); + fontInfo.name = aFontName; + fontInfo.bbox = aFontBBox; - this.parser = new Type1Parser(ASCIIStream, binaryStream); - var fontName = this.parser.parse(); - this.font = PSFonts.get(fontName); - this.data = this.convertToCFF(this.font); + // XXX + this.glyphs = fontInfo.charstrings; + + this.data = this.convertToCFF(fontInfo); var end = Date.now(); //log("Time to parse font is:" + (end - start)); }; @@ -1537,11 +1294,11 @@ CFF.prototype = { } }, - getOrderedCharStrings: function(aFont) { + getOrderedCharStrings: function(aGlyphs) { var charstrings = []; - var glyphs = aFont.get("CharStrings") - glyphs.forEach(function(glyph, glyphData) { + for (var i = 0; i < aGlyphs.length; i++) { + var glyph = aGlyphs[i].glyph; var unicode = GlyphsUnicode[glyph]; if (!unicode) { if (glyph != ".notdef") @@ -1554,10 +1311,10 @@ CFF.prototype = { charstrings.push({ glyph: glyph, unicode: unicode, - charstring: glyphData.slice() + charstring: aGlyphs[i].data.slice() }); } - }); + }; charstrings.sort(function(a, b) { return a.unicode > b.unicode; @@ -1565,20 +1322,20 @@ CFF.prototype = { return charstrings; }, - convertToCFF: function(aFont) { + convertToCFF: function(aFontInfo) { var debug = false; function dump(aMsg) { if (debug) log(aMsg); }; - var charstrings = this.getOrderedCharStrings(aFont); + var charstrings = this.getOrderedCharStrings(aFontInfo.charstrings); var charstringsCount = 0; var charstringsDataLength = 0; var glyphs = []; var glyphsChecker = {}; - var subrs = aFont.get("Private").get("Subrs"); + var subrs = aFontInfo.subrs; var parser = new Type1Parser(); for (var i = 0; i < charstrings.length; i++) { var charstring = charstrings[i].charstring.slice(); @@ -1604,19 +1361,18 @@ CFF.prototype = { cff.set(header); // Names Index - var nameIndex = this.createCFFIndexHeader([aFont.get("FontName")]); + 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 fontInfo = aFont.get("FontInfo"); - var version = fontInfo.get("version"); - var notice = fontInfo.get("Notice"); - var fullName = fontInfo.get("FullName"); - var familyName = fontInfo.get("FamilyName"); - var weight = fontInfo.get("Weight"); + var version = ""; + var notice = ""; + var fullName = ""; + var familyName = ""; + var weight = ""; var strings = [version, notice, fullName, familyName, weight]; var stringsIndex = this.createCFFIndexHeader(strings); @@ -1692,7 +1448,7 @@ CFF.prototype = { 248, 31, 4 // Weight ]; - var fontBBox = aFont.get("FontBBox"); + var fontBBox = aFontInfo.bbox; for (var i = 0; i < fontBBox.length; i++) topDictIndex = topDictIndex.concat(this.encodeNumber(fontBBox[i])); topDictIndex.push(5) // FontBBox; diff --git a/test.js b/test.js index 1dffac549..0fdb2aacf 100644 --- a/test.js +++ b/test.js @@ -119,8 +119,10 @@ function displayPage(num) { } } + var fontBBox = descriptor.get("FontBBox"); + var subtype = fontDict.get("Subtype").name; - new Font(fontName, fontFile, encodingMap, charset, subtype); + new Font(fontName, fontFile, encodingMap, charset, fontBBox, subtype); return fontsReady = false; } else if (font.loading) { return fontsReady = false; From 97e8a563232d53aba0680a0febed845462946463 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 16 Jun 2011 01:09:17 +0200 Subject: [PATCH 59/77] Remove some useless JS function calls --- PDFFont.js | 82 +++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index e54f3ec4b..f052ecf9f 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1096,9 +1096,9 @@ var Type1Parser = function() { token = ""; glyph = ""; - while ((c = eexecString[++i]) != 0x20 && i < count) + while ((c = eexecString[++i]) != 0x20) glyph += String.fromCharCode(c); - } else if (c == 0x2F && eexecString[i+1] == 0x53 && !inGlyphs && !inSubrs) { + } else if (!inSubrs && !inGlyphs && c == 0x2F && eexecString[i+1] == 0x53) { while ((c = eexecString[++i]) != 0x20) {}; inSubrs = true; } else if (c == 0x20) { @@ -1127,7 +1127,9 @@ var Type1Parser = function() { * chapter 8. */ this.flattenCharstring = function(aCharstring, aSubrs) { + var operandStackIndex = 0; operandStack.clear(); + executionStack.clear(); executionStack.push(aCharstring.slice()); @@ -1135,48 +1137,13 @@ var Type1Parser = function() { var lastPoint = 0; while (true) { var obj = nextInStack(); - if (IsBool(obj) || IsInt(obj) || IsNum(obj)) { - dump("Value: " + obj); + if (IsInt(obj) || IsBool(obj)) { operandStack.push(obj); - } else if (IsString(obj)) { - dump("String: " + obj); + } else { switch (obj) { - case "hsbw": - var charWidthVector = operandStack.pop(); - var leftSidebearing = operandStack.pop(); - operandStack.push(charWidthVector); - - if (leftSidebearing) { - operandStack.push(leftSidebearing); - operandStack.push("hmoveto"); - } - break; - - case "div": - var num2 = operandStack.pop(); - var num1 = operandStack.pop(); - operandStack.push(num2 / num1); - break; - - case "setcurrentpoint": - case "dotsection": - case "seac": - case "sbw": - error(obj + " parsing is not implemented (yet)"); - break; - - case "closepath": - case "return": - break; - case "vstem3": - case "vstem": - operandStack.push("vstem"); - break; - - case "hstem": case "hstem3": - operandStack.push("hstem"); + operandStack.push(obj.slice(0, 5)); break; case "callsubr": @@ -1196,12 +1163,40 @@ var Type1Parser = function() { operandStack.push("callothersubr"); break; + case "div": + var num2 = operandStack.pop(); + var num1 = operandStack.pop(); + operandStack.push(num2 / num1); + break; + + case "pop": + operandStack.pop(); + break; + + case "closepath": + case "return": + break; + + case "hsbw": + var charWidthVector = operandStack.pop(); + var leftSidebearing = operandStack.pop(); + operandStack.push(charWidthVector); + + if (leftSidebearing) { + operandStack.push(leftSidebearing); + operandStack.push("hmoveto"); + } + break; + case "endchar": operandStack.push("endchar"); return operandStack.clone(); - case "pop": - operandStack.pop(); + case "setcurrentpoint": + case "dotsection": + case "seac": + case "sbw": + error(obj + " parsing is not implemented (yet)"); break; default: @@ -1214,8 +1209,6 @@ var Type1Parser = function() { }; var CFF = function(aFontName, aFontBBox, aFontFile) { - var start = Date.now(); - // Get the data block containing glyphs and subrs informations var length1 = aFontFile.dict.get("Length1"); var length2 = aFontFile.dict.get("Length2"); @@ -1223,6 +1216,7 @@ var CFF = function(aFontName, aFontBBox, aFontFile) { 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; From 509d608a3a08f2dbfd6e20dd7a8ceb9ccc58db42 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 16 Jun 2011 01:30:47 +0200 Subject: [PATCH 60/77] Use spaces to compare font size to detect when the @font-face rule works, this seems to be more accurate --- PDFFont.js | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index f052ecf9f..a8205753e 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -131,12 +131,20 @@ Font.prototype = { // 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 ? (80 * fontCount) : "-200") + "px; left: 100px;"; + 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", 100); - canvas.setAttribute("heigth", 70); + canvas.setAttribute("width", 340); + canvas.setAttribute("heigth", 100); document.body.appendChild(canvas); // Retrieve font charset @@ -146,16 +154,21 @@ Font.prototype = { while (count-- && charset.length <= 30) charset = charset.concat(charset.slice()); - // Get the font size canvas think it will be + // Get the font size canvas think it will be for 'spaces' var ctx = canvas.getContext("2d"); - var testString = ""; - for (var i = 0; i < charset.length; i++) { - var unicode = new Number("0x" + GlyphsUnicode[charset[i]]); - if (!unicode) - error("Unicode for " + charset[i] + " is has not been found in the glyphs list"); - testString += String.fromCharCode(unicode); + 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 = new Number("0x" + 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 = "20px " + fontName + ", Symbol"; + ctx.font = "bold italic 20px " + fontName + ", Symbol, Arial"; var textWidth = ctx.mozMeasureText(testString); if (debug) @@ -163,7 +176,7 @@ Font.prototype = { var start = Date.now(); var interval = window.setInterval(function(self) { - ctx.font = "20px " + fontName + ", Symbol"; + 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 From 1923337bab3dd38e98bf1c66400a6d85d71ab139 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 16 Jun 2011 02:17:45 +0200 Subject: [PATCH 61/77] Change the nominalWidth to not use the format 28,b0,b1 but b0-139 in order to pass the sanitizer and disable TrueType support until it fully works --- PDFFont.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index a8205753e..8c3abc7ec 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -31,7 +31,7 @@ var fontCount = 0; var Fonts = { _active: null, get active() { - return this._active; + return this._active || { encoding: {} }; }, set active(aFontName) { @@ -39,12 +39,7 @@ var Fonts = { }, unicodeFromCode: function fonts_unicodeFromCode(aCode) { - var active = this._active; - if (!active || !active.encoding) - return aCode; - - var difference = active.encoding[aCode]; - var unicode = GlyphsUnicode[difference]; + var unicode = GlyphsUnicode[this.active.encoding[aCode]]; return unicode ? "0x" + unicode : aCode; } }; @@ -84,6 +79,15 @@ var Font = function(aName, aFile, aEncoding, aCharset, aBBox, aType) { 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; @@ -1140,9 +1144,7 @@ var Type1Parser = function() { * chapter 8. */ this.flattenCharstring = function(aCharstring, aSubrs) { - var operandStackIndex = 0; operandStack.clear(); - executionStack.clear(); executionStack.push(aCharstring.slice()); @@ -1434,8 +1436,7 @@ CFF.prototype = { log("Glyph " + i + " has a wrong value: " + c + " in charstring: " + data); log("the default value is glyph " + charstrings[i].glyph + " and is supposed to be: " + charstrings[i].charstring); } - for (var k = 0; k < bytes.length; k++) - charstring.push(bytes[k]); + charstring = charstring.concat(bytes); } } r.push(charstring); @@ -1503,7 +1504,7 @@ CFF.prototype = { var defaultWidth = this.encodeNumber(0); var privateData = [].concat( defaultWidth, [20], - defaultWidth, [21], + [139, 21], // nominalWidth [ 119, 159, 248, 97, 159, 247, 87, 159, 6, 30, 10, 3, 150, 37, 255, 12, 9, From c9e0b056782a306da7f980db00388e73e0798572 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 16 Jun 2011 03:55:45 +0200 Subject: [PATCH 62/77] Resolve the char->glyphs mapping issue --- PDFFont.js | 2 +- pdf.js | 15 +++++++++------ test.js | 19 +++++++++++-------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index d106e0b23..48554d9d1 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -31,7 +31,7 @@ var fontCount = 0; var Fonts = { _active: null, get active() { - return this._active || { encoding: {} }; + return this._active || { encoding: [] }; }, set active(aName) { diff --git a/pdf.js b/pdf.js index 2b7eb1e1b..fe636bcf9 100644 --- a/pdf.js +++ b/pdf.js @@ -795,7 +795,6 @@ var Lexer = (function() { } } - x = Fonts.unicodeFromCode(x); str += String.fromCharCode(x); break; case '\r': @@ -811,8 +810,7 @@ var Lexer = (function() { } break; default: - var unicode = Fonts.unicodeFromCode(ch.charCodeAt(0)); - str += String.fromCharCode(unicode); + str += ch; break; } } while (!done); @@ -1730,7 +1728,7 @@ var CanvasGraphics = (function() { 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"); @@ -1760,7 +1758,7 @@ var CanvasGraphics = (function() { for (var j = 0; j < widths.length; j++) { var index = widths[j]; if (index) - charset.push(encoding[j + firstchar]); + charset.push(encoding[j + firstchar]); } } } @@ -2054,7 +2052,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.js b/test.js index 75b720002..d0d386872 100644 --- a/test.js +++ b/test.js @@ -1,7 +1,7 @@ /* -*- 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, pageTimeout; +var pdfDocument, canvas, pageDisplay, pageNum, pageInterval; function load() { canvas = document.getElementById("canvas"); canvas.mozOpaque = true; @@ -48,7 +48,7 @@ function gotoPage(num) { function displayPage(num) { if (pageNum != num) - window.clearTimeout(pageTimeout); + window.clearTimeout(pageInterval); document.getElementById("pageNumber").value = num; @@ -57,7 +57,6 @@ function displayPage(num) { var page = pdfDocument.getPage(pageNum = num); var t1 = Date.now(); - var ctx = canvas.getContext("2d"); ctx.save(); ctx.fillStyle = "rgb(255, 255, 255)"; @@ -73,17 +72,21 @@ function displayPage(num) { page.compile(gfx, fonts); var t2 = Date.now(); - var interval = setInterval(function() { + // 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; } - - page.display(gfx); var t3 = Date.now(); + + clearInterval(pageInterval); + page.display(gfx); + + var t4 = Date.now(); + var infoDisplay = document.getElementById("info"); - infoDisplay.innerHTML = "Time to load/compile/render: "+ (t1 - t0) + "/" + (t2 - t1) + "/" + (t3 - t2) + " ms"; - clearInterval(interval); + infoDisplay.innerHTML = "Time to load/compile/fonts/render: "+ (t1 - t0) + "/" + (t2 - t1) + "/" + (t3 - t2) + "/" + (t4 - t3) + " ms"; }, 10); } From 327e36b347102f7ed3cd76243dcae38b3b50e63d Mon Sep 17 00:00:00 2001 From: Soumya Deb Date: Thu, 16 Jun 2011 12:14:02 +0530 Subject: [PATCH 63/77] Test-page updated to allow the user open local PDFs --- test.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test.html b/test.html index 9cadf2e1f..aea4ec5ba 100644 --- a/test.html +++ b/test.html @@ -46,13 +46,16 @@ function queryParams() { } var canvas, numPages, pageDisplay, pageNum; -function load() { +function load(userInput) { 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"; + fileName = userInput; + if(!userInput){ + fileName = queryParams().file || "compressed.tracemonkey-pldi-09.pdf"; + } open(fileName); } @@ -132,6 +135,9 @@ function gotoPage(num) {
+ + Date: Thu, 16 Jun 2011 09:34:43 +0200 Subject: [PATCH 64/77] Remove some debug leftovers and add some comments about future directions for the code --- PDFFont.js | 192 +++++++++++++++++++++++++++++++----------------- PDFFontUtils.js | 21 +++++- 2 files changed, 142 insertions(+), 71 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 48554d9d1..4278ae29a 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -16,10 +16,10 @@ var kMaxGlyphsCount = 65526; */ var kMaxWaitForFontFace = 1000; - /* - * Useful for debugging when you want to certains operations depending on how - * many fonts are loaded. - */ +/** + * Useful for debugging when you want to certains operations depending on how + * many fonts are loaded. + */ var fontCount = 0; /** @@ -55,7 +55,7 @@ var Fonts = { * 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. * - * XXX There is now too many parameters, this should be turned into an + * 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) { @@ -110,6 +110,15 @@ var Font = function(aName, aFile, aEncoding, aCharset, aBBox, aType) { 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, @@ -477,7 +486,6 @@ Font.prototype = { /** HMTX */ hmtx = [0x01, 0xF4, 0x00, 0x00]; for (var i = 0; i < charstrings.length; i++) { - // XXX this can easily broke var charstring = charstrings[i].charstring; var width = FontsUtils.integerToBytes(charstring[1], 2); var lsb = FontsUtils.integerToBytes(charstring[0], 2); @@ -503,7 +511,7 @@ Font.prototype = { this._createTableEntry(otf, offsets, "name", name); /** POST */ - // XXX get those info from the Font dict! + // FIXME Get those informations from the FontInfo structure post = [ 0x00, 0x03, 0x00, 0x00, // Version number 0x00, 0x00, 0x01, 0x00, // italicAngle @@ -528,13 +536,15 @@ Font.prototype = { var fontData = []; for (var i = 0; i < offsets.currentOffset; i++) fontData.push(otf[i]); - - //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf"); 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 = { integerToBytes: function fu_integerToBytes(aValue, aBytesCount) { var bytes = []; @@ -549,7 +559,7 @@ var FontsUtils = { return bytes; }, - bytesToInteger: function(aBytesArray) { + bytesToInteger: function fu_bytesToInteger(aBytesArray) { var value = 0; for (var i = 0; i < aBytesArray.length; i++) value = (value << 8) + aBytesArray[i]; @@ -575,9 +585,14 @@ var FontsUtils = { /** Implementation dirty logic starts here */ /** - * At the moment TrueType is just a stub that does mostly nothing but in a - * (near?) future this class will rewrite the font to ensure it is well formed - * and valid in the point of view of the sanitizer. + * 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); @@ -604,6 +619,8 @@ var TrueType = function(aFile) { tables.push(table); } + + // Tables needs to be written by ascendant alphabetic order tables.sort(function(a, b) { return a.tag > b.tag; }); @@ -714,7 +731,6 @@ var TrueType = function(aFile) { fontData.push(ttf[i]); this.data = ttf; - //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".ttf"); return; } else if (requiredTables.lenght) { error("Table " + requiredTables[0] + " is missing from the TruType font"); @@ -825,6 +841,7 @@ TrueType.prototype = { } }; + /** * This dictionary holds decoded fonts data. */ @@ -954,19 +971,58 @@ var Type1Parser = function() { "6": "hlineto", "7": "vlineto", "8": "rrcurveto", - "9": "closepath", + + // 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": { - "0": "dotsection", - "1": "vstem3", - "3": "hstem3", - "6": "seac", - "7": "sbw", + // 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", - "33": "setcurrentpoint" + + // 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", @@ -986,12 +1042,27 @@ var Type1Parser = function() { value = aStream.getByte(); if (value < 32) { + var command = null; if (value == 12) { - value = charStringDictionary["12"][aStream.getByte()]; + var escape = aStream.getByte(); + command = charStringDictionary["12"][escape]; i++; } else { - value = charStringDictionary[value]; + 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) { @@ -1140,7 +1211,7 @@ var Type1Parser = function() { * Flatten the commands by interpreting the postscript code and replacing * every 'callsubr', 'callothersubr' by the real commands. * At the moment OtherSubrs are not fully supported and only otherSubrs 0-4 - * as descrived in 'Using Subroutines' of 'Adobe Type 1 Font Format', + * as described in 'Using Subroutines' of 'Adobe Type 1 Font Format', * chapter 8. */ this.flattenCharstring = function(aCharstring, aSubrs) { @@ -1156,11 +1227,6 @@ var Type1Parser = function() { operandStack.push(obj); } else { switch (obj) { - case "vstem3": - case "hstem3": - operandStack.push(obj.slice(0, 5)); - break; - case "callsubr": var index = operandStack.pop(); executionStack.push(aSubrs[index].slice()); @@ -1188,7 +1254,6 @@ var Type1Parser = function() { operandStack.pop(); break; - case "closepath": case "return": break; @@ -1207,13 +1272,6 @@ var Type1Parser = function() { operandStack.push("endchar"); return operandStack.clone(); - case "setcurrentpoint": - case "dotsection": - case "seac": - case "sbw": - error(obj + " parsing is not implemented (yet)"); - break; - default: operandStack.push(obj); break; @@ -1345,6 +1403,20 @@ CFF.prototype = { var glyphs = []; var glyphsChecker = {}; var subrs = aFontInfo.subrs; + + // FIXME This code is actually the only reason the dummy PS Interpreter + // called Type1Parser continue to lives, basically the goal here is + // to embed the OtherSubrs/Subrs into the charstring directly. + // But since Type2 charstrings use a bias to index Subrs and can + // theorically store twice the number of Type1 we could directly + // save the OtherSubrs and Subrs in the Type2 table for Subrs + // and avoid this 'flattening' slow method. + // + // The other thinds done by this method is splitting the initial + // 'width lsb hswb' command of Type1 to something similar in Type2 + // that is: 'width dx moveto' but this can be done in the + // decodeCharstring method directly (maybe one day it will be called + // translateCharstring?) var parser = new Type1Parser(); for (var i = 0; i < charstrings.length; i++) { var charstring = charstrings[i].charstring.slice(); @@ -1417,7 +1489,11 @@ CFF.prototype = { "hvcurveto": 31, }; - // Encode the glyph and add it to the FUX + // FIXME Concatenating array with this algorithm (O²) is expensive and + // can be avoided if the voodoo's dance of charstrings decoding + // encoding is left for dead. Actually charstrings command number + // are converted to a string and then back to a number with the + // next few lines of code... var r = [[0x40, 0x0E]]; for (var i = 0; i < glyphs.length; i++) { var data = glyphs[i].slice(); @@ -1427,7 +1503,7 @@ CFF.prototype = { if (!IsNum(c)) { var token = getNumFor[c]; if (!token) - error(c); + error("Token " + c + " is not recognized in charstring " + data); charstring.push(token); } else { try { @@ -1445,7 +1521,6 @@ CFF.prototype = { var charstringsIndex = this.createCFFIndexHeader(r, true); charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why? - //Top Dict Index var topDictIndex = [ 0x00, 0x01, 0x01, 0x01, 0x30, @@ -1480,25 +1555,17 @@ CFF.prototype = { topDictIndex.push(18); // Private topDictIndex = topDictIndex.join(" ").split(" "); - // Top Dict Index - cff.set(topDictIndex, currentOffset); - currentOffset += topDictIndex.length; + var indexes = [ + topDictIndex, stringsIndex, + globalSubrsIndex, charset, + charstringsIndex + ]; - // Strings Index - cff.set(stringsIndex, currentOffset); - currentOffset += stringsIndex.length; - - // Global Subrs Index - cff.set(globalSubrsIndex, currentOffset); - currentOffset += globalSubrsIndex.length; - - // Charset Index - cff.set(charset, currentOffset); - currentOffset += charset.length; - - // Fill charstrings data - cff.set(charstringsIndex, currentOffset); - currentOffset += charstringsIndex.length; + 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); @@ -1532,19 +1599,10 @@ CFF.prototype = { cff.set(shit, currentOffset); currentOffset += shit.length; - - dump("==================== debug ===================="); - //var file = new Uint8Array(cff, 0, currentOffset); - //var parser = new Type2Parser(); - //parser.parse(new Stream(file)); - var fontData = []; for (var i = 0; i < currentOffset; i++) fontData.push(cff[i]); - //log("== write to file"); - //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".cff"); - return fontData; } }; diff --git a/PDFFontUtils.js b/PDFFontUtils.js index 072dd48f1..e242121db 100644 --- a/PDFFontUtils.js +++ b/PDFFontUtils.js @@ -349,13 +349,26 @@ var Type2Parser = function(aFilePath) { }; /* -var cff = new Type2Parser("test.cff"); -cff.parse(); -*/ + * 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 (works only on Firefox in privilege mode"); + * 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"); From eb6f7499dc8c556ef3f8f4e40d346f6bf194953a Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 06:02:29 +0200 Subject: [PATCH 65/77] Rework some code to enhance performance (CIIM6/CIIM9 are rejected by the sanitizer now) --- PDFFont.js | 338 ++++++++++++++++++++---------------------------- PDFFontUtils.js | 3 +- 2 files changed, 142 insertions(+), 199 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 4278ae29a..1bf437066 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -546,7 +546,14 @@ Font.prototype = { * to fonts in particular and needs to be share between them. */ var FontsUtils = { + _bytesArray: new Uint8Array(4), integerToBytes: function fu_integerToBytes(aValue, aBytesCount) { + // If we want only one byte, take a fast path + if (aBytesCount == 1) { + this._bytesArray.set([aValue]); + return this._bytesArray[0]; + } + var bytes = []; for (var i = 0; i < aBytesCount; i++) bytes[i] = 0x00; @@ -1087,61 +1094,6 @@ var Type1Parser = function() { return charString; }; - /* - * The operand stack holds arbitrary PostScript objects that are the operands - * and results of PostScript operators being executed. The interpreter pushes - * objects on the operand stack when it encounters them as literal data in a - * program being executed. When an operator requires one or more operands, it - * obtains them by popping them off the top of the operand stack. When an - * operator returns one or more results, it does so by pushing them on the - * operand stack. - */ - var operandStack = new Stack(40); - - // Flag indicating if the topmost operand of the operandStack is an array - var operandIsArray = 0; - - /* - * The dictionary stack holds only dictionary objects. The current set of - * dictionaries on the dictionary stack defines the environment for all - * implicit name searches, such as those that occur when the interpreter - * encounters an executable name. The role of the dictionary stack is - * introduced in Section 3.3, “Data Types and Objects,” and is further - * explained in Section 3.5, “Execution.” of the PostScript Language - * Reference. - */ - var systemDict = new Dict(), - globalDict = new Dict(), - userDict = new Dict(); - - var dictionaryStack = new Stack(); - dictionaryStack.push(systemDict); - dictionaryStack.push(globalDict); - dictionaryStack.push(userDict); - - /* - * The execution stack holds executable objects (mainly procedures and files) - * that are in intermediate stages of execution. At any point in the - * execution of a PostScript program, this stack represents the program’s - * call stack. Whenever the interpreter suspends execution of an object to - * execute some other object, it pushes the new object on the execution - * stack. When the interpreter finishes executing an object, it pops that - * object off the execution stack and resumes executing the suspended object - * beneath it. - */ - var executionStack = new Stack(); - - /* - * Return the next token in the execution stack - */ - function nextInStack() { - var currentProcedure = executionStack.peek(); - var command = currentProcedure.shift(); - if (!currentProcedure.length) - executionStack.pop(); - return command; - }; - /** * Returns an object containing a Subrs array and a CharStrings array * extracted from and eexec encrypted block of data @@ -1205,79 +1157,6 @@ var Type1Parser = function() { subrs: subrs, charstrings: glyphs } - }; - - /* - * Flatten the commands by interpreting the postscript code and replacing - * every 'callsubr', 'callothersubr' by the real commands. - * At the moment OtherSubrs are not fully supported and only otherSubrs 0-4 - * as described in 'Using Subroutines' of 'Adobe Type 1 Font Format', - * chapter 8. - */ - this.flattenCharstring = function(aCharstring, aSubrs) { - operandStack.clear(); - executionStack.clear(); - executionStack.push(aCharstring.slice()); - - var leftSidebearing = 0; - var lastPoint = 0; - while (true) { - var obj = nextInStack(); - if (IsInt(obj) || IsBool(obj)) { - operandStack.push(obj); - } else { - switch (obj) { - case "callsubr": - var index = operandStack.pop(); - executionStack.push(aSubrs[index].slice()); - break; - - case "callothersubr": - var index = operandStack.pop(); - var count = operandStack.pop(); - var data = operandStack.pop(); - // XXX The callothersubr needs to support at least the 3 defaults - // otherSubrs of the spec - if (index != 3) - error("callothersubr for index: " + index); - operandStack.push(3); - operandStack.push("callothersubr"); - break; - - case "div": - var num2 = operandStack.pop(); - var num1 = operandStack.pop(); - operandStack.push(num2 / num1); - break; - - case "pop": - operandStack.pop(); - break; - - case "return": - break; - - case "hsbw": - var charWidthVector = operandStack.pop(); - var leftSidebearing = operandStack.pop(); - operandStack.push(charWidthVector); - - if (leftSidebearing) { - operandStack.push(leftSidebearing); - operandStack.push("hmoveto"); - } - break; - - case "endchar": - operandStack.push("endchar"); - return operandStack.clone(); - - default: - operandStack.push(obj); - break; - } - } - } } }; @@ -1339,10 +1218,11 @@ CFF.prototype = { return data; }, - encodeNumber: function(aValue) { + encodeNumber: function(aValue, aIsCharstring) { var x = 0; - // XXX we don't really care about Type2 optimization here... - if (aValue >= -32768 && aValue <= 32767) { + if (aIsCharstring && aValue >= -107 && aValue <= 107) { + return [aValue + 139]; + } else if (aValue >= -32768 && aValue <= 32767) { return [ 28, FontsUtils.integerToBytes(aValue >> 8, 1), @@ -1389,6 +1269,128 @@ CFF.prototype = { 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(aCharstring, aSubrs) { + var i = 0; + while (true) { + var obj = aCharstring[i]; + if (IsString(obj)) { + switch (obj) { + case "callsubr": + var subr = aSubrs[aCharstring[i- 1]].slice(); + if (subr.length > 1) { + subr = this.flattenCharstring(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, 3, "pop", 3); + i -= 2; + } 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": + aCharstring.splice(i - 2, 2); + i -= 1; + break; + + + case "hsbw": + var charWidthVector = aCharstring[i - 1]; + var leftSidebearing = aCharstring[i - 2]; + aCharstring.splice(i - 2, 3, charWidthVector, leftSidebearing, "hmoveto"); + 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 (IsNum(command)) { + var number = this.encodeNumber(command, true); + aCharstring.splice(j, 1); + for (var k = 0; k < number.length; k++) + aCharstring.splice(j + k, 0, number[k]); + j+= number.length - 1; + } else if (IsString(command)) { + var command = this.commandsMap[command]; + if (IsArray(command)) { + aCharstring.splice(j - 1, 1, command[0], command[1]); + j += 1; + } else { + aCharstring[j] = command; + } + } else if (IsArray(command)) { + 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; + } else { // what else? + error("Error while flattening the Type1 charstring: " + aCharstring); + } + } + return aCharstring; + + default: + break; + } + } + i++; + } + error("failing with i = " + i + " in charstring:" + aCharstring + "(" + aCharstring.length + ")"); + }, + convertToCFF: function(aFontInfo) { var debug = false; function dump(aMsg) { @@ -1398,39 +1400,24 @@ CFF.prototype = { 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 = []; - var glyphsChecker = {}; - var subrs = aFontInfo.subrs; - - // FIXME This code is actually the only reason the dummy PS Interpreter - // called Type1Parser continue to lives, basically the goal here is - // to embed the OtherSubrs/Subrs into the charstring directly. - // But since Type2 charstrings use a bias to index Subrs and can - // theorically store twice the number of Type1 we could directly - // save the OtherSubrs and Subrs in the Type2 table for Subrs - // and avoid this 'flattening' slow method. - // - // The other thinds done by this method is splitting the initial - // 'width lsb hswb' command of Type1 to something similar in Type2 - // that is: 'width dx moveto' but this can be done in the - // decodeCharstring method directly (maybe one day it will be called - // translateCharstring?) - var parser = new Type1Parser(); for (var i = 0; i < charstrings.length; i++) { var charstring = charstrings[i].charstring.slice(); var glyph = charstrings[i].glyph; - if (glyphsChecker[glyph]) - error("glyphs already exists!"); - glyphsChecker[glyph] = true; - var flattened = parser.flattenCharstring(charstring, subrs); + var flattened = this.flattenCharstring(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); @@ -1473,52 +1460,7 @@ CFF.prototype = { charset.push(bytes[1]); } - // Convert charstrings - var getNumFor = { - "hstem": 1, - "vstem": 3, - "vmoveto": 4, - "rlineto": 5, - "hlineto": 6, - "vlineto": 7, - "rrcurveto": 8, - "endchar": 14, - "rmoveto": 21, - "hmoveto": 22, - "vhcurveto": 30, - "hvcurveto": 31, - }; - - // FIXME Concatenating array with this algorithm (O²) is expensive and - // can be avoided if the voodoo's dance of charstrings decoding - // encoding is left for dead. Actually charstrings command number - // are converted to a string and then back to a number with the - // next few lines of code... - var r = [[0x40, 0x0E]]; - for (var i = 0; i < glyphs.length; i++) { - var data = glyphs[i].slice(); - var charstring = []; - for (var j = 0; j < data.length; j++) { - var c = data[j]; - if (!IsNum(c)) { - var token = getNumFor[c]; - if (!token) - error("Token " + c + " is not recognized in charstring " + data); - charstring.push(token); - } else { - try { - var bytes = this.encodeNumber(c); - } catch(e) { - log("Glyph " + i + " has a wrong value: " + c + " in charstring: " + data); - log("the default value is glyph " + charstrings[i].glyph + " and is supposed to be: " + charstrings[i].charstring); - } - charstring = charstring.concat(bytes); - } - } - r.push(charstring); - } - - var charstringsIndex = this.createCFFIndexHeader(r, true); + var charstringsIndex = this.createCFFIndexHeader([[0x40, 0x0E]].concat(glyphs), true); charstringsIndex = charstringsIndex.join(" ").split(" "); // XXX why? //Top Dict Index diff --git a/PDFFontUtils.js b/PDFFontUtils.js index e242121db..086648fe2 100644 --- a/PDFFontUtils.js +++ b/PDFFontUtils.js @@ -310,7 +310,8 @@ var Type2Parser = function(aFilePath) { // 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); + var subrs = readFontIndexData(aStream, true); + dump(subrs); // Reading Private Dict var private = font.get("Private"); From 88512fbdd9fda60993ad718b97a407e81f5f33c1 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 06:06:24 +0200 Subject: [PATCH 66/77] Remove some leftovers from the previous patch --- PDFFont.js | 45 --------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 1bf437066..4706121f2 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -589,8 +589,6 @@ var FontsUtils = { }; -/** Implementation dirty logic starts here */ - /** * 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. @@ -852,49 +850,6 @@ TrueType.prototype = { /** * This dictionary holds decoded fonts data. */ -var PSFonts = new Dict(); - -var Stack = function(aStackSize) { - var innerStack = new Array(aStackSize || 0); - - this.push = function(aOperand) { - innerStack.push(aOperand); - }; - - this.pop = function() { - if (!this.count()) - throw new Error("stackunderflow"); - return innerStack.pop(); - }; - - this.peek = function() { - if (!this.count()) - return null; - return innerStack[innerStack.length - 1]; - }; - - this.get = function(aIndex) { - return innerStack[aIndex]; - }; - - this.clear = function() { - innerStack = []; - }; - - this.count = function() { - return innerStack.length; - }; - - this.dump = function() { - for (var i = 0; i < this.length; i++) - log(innerStack[i]); - }; - - this.clone = function() { - return innerStack.slice(); - }; -}; - var Type1Parser = function() { // Turn on this flag for additional debugging logs var debug = false; From 01847a0e29e93ad8585f2bbe5575c88b0a38e0e3 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 06:44:16 +0200 Subject: [PATCH 67/77] Get rid or IsNum/IsString/IsArray in flattenCharstring --- PDFFont.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 4706121f2..00637f2cf 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -188,7 +188,7 @@ Font.prototype = { ctx.fillText(testString, 20, 20); var start = Date.now(); - var interval = window.setInterval(function(self) { + 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 @@ -1250,7 +1250,7 @@ CFF.prototype = { var i = 0; while (true) { var obj = aCharstring[i]; - if (IsString(obj)) { + if (obj.charAt) { switch (obj) { case "callsubr": var subr = aSubrs[aCharstring[i- 1]].slice(); @@ -1309,13 +1309,13 @@ CFF.prototype = { // 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 (IsNum(command)) { + if (parseFloat(command) == command) { var number = this.encodeNumber(command, true); aCharstring.splice(j, 1); for (var k = 0; k < number.length; k++) aCharstring.splice(j + k, 0, number[k]); j+= number.length - 1; - } else if (IsString(command)) { + } else if (command.charAt) { var command = this.commandsMap[command]; if (IsArray(command)) { aCharstring.splice(j - 1, 1, command[0], command[1]); @@ -1323,7 +1323,7 @@ CFF.prototype = { } else { aCharstring[j] = command; } - } else if (IsArray(command)) { + } else { aCharstring.splice(j, 1); // command has already been translated, just add them to the @@ -1331,8 +1331,6 @@ CFF.prototype = { for (var k = 0; k < command.length; k++) aCharstring.splice(j + k, 0, command[k]); j+= command.length - 1; - } else { // what else? - error("Error while flattening the Type1 charstring: " + aCharstring); } } return aCharstring; From 89c9bc39de7577c4a55430c609435c424b02d67d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 06:53:18 +0200 Subject: [PATCH 68/77] Add a direct translation to one of the way to format charstring number in flattenCharstring (28, x, y) --- PDFFont.js | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 00637f2cf..24c4a8c3e 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1173,24 +1173,13 @@ CFF.prototype = { return data; }, - encodeNumber: function(aValue, aIsCharstring) { + encodeNumber: function(aValue) { var x = 0; - if (aIsCharstring && aValue >= -107 && aValue <= 107) { - return [aValue + 139]; - } else if (aValue >= -32768 && aValue <= 32767) { - return [ - 28, - FontsUtils.integerToBytes(aValue >> 8, 1), - FontsUtils.integerToBytes(aValue, 1) - ]; + if (aValue >= -32768 && aValue <= 32767) { + return [ 28, aValue >> 8, aValue ]; } else if (aValue >= (-2147483647-1) && aValue <= 2147483647) { return [ - 0xFF, - FontsUtils.integerToBytes(aValue >> 24, 1), - FontsUtils.integerToBytes(aValue >> 16, 1), - FontsUtils.integerToBytes(aValue >> 8, 1), - FontsUtils.integerToBytes(aValue, 1) - ]; + 0xFF, aValue >> 24, Value >> 16, aValue >> 8, aValue ]; } else { error("Value: " + aValue + " is not allowed"); } @@ -1227,7 +1216,7 @@ CFF.prototype = { /* * 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 */ @@ -1310,11 +1299,8 @@ CFF.prototype = { for (var j = 0; j < aCharstring.length; j++) { var command = aCharstring[j]; if (parseFloat(command) == command) { - var number = this.encodeNumber(command, true); - aCharstring.splice(j, 1); - for (var k = 0; k < number.length; k++) - aCharstring.splice(j + k, 0, number[k]); - j+= number.length - 1; + aCharstring.splice(j, 1, 28, command >> 8, command); + j+= 2; } else if (command.charAt) { var command = this.commandsMap[command]; if (IsArray(command)) { From d31bc90c855489a86c2de2f51a78981efdddb763 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 07:14:11 +0200 Subject: [PATCH 69/77] Use a typed array in the CMAP construction function --- PDFFont.js | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 24c4a8c3e..95d80bfc8 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -274,15 +274,15 @@ Font.prototype = { }, _createCMAPTable: function font_createCMAPTable(aGlyphs) { - var characters = new Array(kMaxGlyphsCount); - for (var i = 0; i < aGlyphs.length; i++) { + 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 = []; - for (var i = 0; i < characters.length; i++) { + var count = characters.length; + for (var i = 0; i < count; i++) { if (characters[i]) { range.push(i); } else if (range.length) { @@ -548,22 +548,18 @@ Font.prototype = { var FontsUtils = { _bytesArray: new Uint8Array(4), integerToBytes: function fu_integerToBytes(aValue, aBytesCount) { - // If we want only one byte, take a fast path + var bytes = this._bytesArray; + if (aBytesCount == 1) { - this._bytesArray.set([aValue]); - return this._bytesArray[0]; + 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]]; } - - var bytes = []; - for (var i = 0; i < aBytesCount; i++) - bytes[i] = 0x00; - - do { - bytes[--aBytesCount] = (aValue & 0xFF); - aValue = aValue >> 8; - } while (aBytesCount && aValue > 0); - - return bytes; }, bytesToInteger: function fu_bytesToInteger(aBytesArray) { @@ -875,7 +871,7 @@ var Type1Parser = function() { var value = ""; var count = aStream.length; for (var i = 0; i < count; i++) { - value = aStream.getByte(); + value = aStream[i]; if (aByteArray) decryptedString[i] = value ^ (r >> 8); else @@ -1054,7 +1050,7 @@ var Type1Parser = function() { * extracted from and eexec encrypted block of data */ this.extractFontInfo = function(aStream) { - var eexecString = decrypt(new Stream(aStream), kEexecEncryptionKey, 4, true); + var eexecString = decrypt(aStream, kEexecEncryptionKey, 4, true); var subrs = [], glyphs = []; var inSubrs = inGlyphs = false; var glyph = ""; @@ -1070,16 +1066,16 @@ var Type1Parser = function() { if (inSubrs && c == 0x52) { length = parseInt(length); - var stream = new Stream(eexecString.slice(i + 3, i + 3 + length)); - var encodedSubr = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); + var data = eexecString.slice(i + 3, i + 3 + length); + var encodedSubr = decrypt(data, kCharStringsEncryptionKey, 4).join(""); var subr = decodeCharString(new StringStream(encodedSubr)); subrs.push(subr); i += 3 + length; } else if (inGlyphs && c == 0x52) { length = parseInt(length); - var stream = new Stream(eexecString.slice(i + 3, i + 3 + length)); - var encodedCharstring = decrypt(stream, kCharStringsEncryptionKey, 4).join(""); + var data = eexecString.slice(i + 3, i + 3 + length); + var encodedCharstring = decrypt(data, kCharStringsEncryptionKey, 4).join(""); var subr = decodeCharString(new StringStream(encodedCharstring)); glyphs.push({ From 35ceea1ff20b9f1b65b1dd2ef872401e7adeeb45 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 07:48:45 +0200 Subject: [PATCH 70/77] Do not use stream when it is not necessary --- PDFFont.js | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 95d80bfc8..5fa463250 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -990,32 +990,30 @@ var Type1Parser = function() { "31": "hvcurveto" }; - function decodeCharString(aStream) { - var start = Date.now(); + function decodeCharString(aArray) { var charString = []; var value = ""; - var count = aStream.length; + var count = aArray.length; for (var i = 0; i < count; i++) { - value = aStream.getByte(); + value = parseInt(aArray[i]); if (value < 32) { var command = null; if (value == 12) { - var escape = aStream.getByte(); + var escape = aArray[++i]; command = charStringDictionary["12"][escape]; - i++; } 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) + if (!command && i < count) { continue; - else if (!command) + } else if (!command) { break; - else if (command == -1) { + } else if (command == -1) { log("decodeCharstring: " + charString); error("Support for Type1 command " + value + " (" + escape + ") is not implemented"); } @@ -1024,24 +1022,19 @@ var Type1Parser = function() { } else if (value <= 246) { value = parseInt(value) - 139; } else if (value <= 250) { - value = ((value - 247) * 256) + parseInt(aStream.getByte()) + 108; - i++; + value = ((value - 247) * 256) + parseInt(aArray[++i]) + 108; } else if (value <= 254) { - value = -((value - 251) * 256) - parseInt(aStream.getByte()) - 108; - i++; + value = -((value - 251) * 256) - parseInt(aArray[++i]) - 108; } else { - var byte = aStream.getByte(); + var byte = aArray[++i]; var high = (byte >> 1); - value = (byte - high) << 24 | aStream.getByte() << 16 | - aStream.getByte() << 8 | aStream.getByte(); - i += 4; + value = (byte - high) << 24 | aArray[++i] << 16 | + aArray[++i] << 8 | aArray[++i]; } charString.push(value); } - var end = Date.now(); - dump("Time to decode charString of length " + count + " is " + (end - start)); return charString; }; @@ -1067,16 +1060,16 @@ var Type1Parser = function() { if (inSubrs && c == 0x52) { length = parseInt(length); var data = eexecString.slice(i + 3, i + 3 + length); - var encodedSubr = decrypt(data, kCharStringsEncryptionKey, 4).join(""); - var subr = decodeCharString(new StringStream(encodedSubr)); + 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).join(""); - var subr = decodeCharString(new StringStream(encodedCharstring)); + var encodedCharstring = decrypt(data, kCharStringsEncryptionKey, 4, true); + var subr = decodeCharString(encodedCharstring); glyphs.push({ glyph: glyph, @@ -1125,12 +1118,11 @@ var CFF = function(aFontName, aFontBBox, aFontFile) { fontInfo.name = aFontName; fontInfo.bbox = aFontBBox; - // XXX + // 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(); - //log("Time to parse font is:" + (end - start)); }; CFF.prototype = { @@ -1232,13 +1224,22 @@ CFF.prototype = { }, flattenCharstring: function(aCharstring, aSubrs) { + var original = aCharstring.slice(); var i = 0; while (true) { var obj = aCharstring[i]; if (obj.charAt) { switch (obj) { case "callsubr": - var subr = aSubrs[aCharstring[i- 1]].slice(); + if (aCharstring[i - 1] == 351) { + log(original); + log(aCharstring); + error("..."); + aCharstring.splice(i - 1, 2); + continue; + } + + var subr = aSubrs[aCharstring[i - 1]].slice(); if (subr.length > 1) { subr = this.flattenCharstring(subr, aSubrs); subr.pop(); From b5915ab3cd823533d6a0eb478c0d360e9b7baa76 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 08:36:52 +0200 Subject: [PATCH 71/77] Fix CIMM6/CIIM9 --- PDFFont.js | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 5fa463250..2db7e745f 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -1223,31 +1223,25 @@ CFF.prototype = { "hvcurveto": 31, }, - flattenCharstring: function(aCharstring, aSubrs) { + 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": - if (aCharstring[i - 1] == 351) { - log(original); - log(aCharstring); - error("..."); - aCharstring.splice(i - 1, 2); - continue; - } - var subr = aSubrs[aCharstring[i - 1]].slice(); if (subr.length > 1) { - subr = this.flattenCharstring(subr, aSubrs); + subr = this.flattenCharstring(aGlyph, subr, aSubrs); subr.pop(); aCharstring.splice(i - 1, 2, subr); - } - else + } else { aCharstring.splice(i - 1, 2); - + } i -= 1; break; @@ -1262,8 +1256,8 @@ CFF.prototype = { error("callothersubr for index: " + index + " (" + aCharstring + ")"); if (!data) { - aCharstring.splice(i - 2, 3, "pop", 3); - i -= 2; + 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); @@ -1279,7 +1273,10 @@ CFF.prototype = { break; case "pop": - aCharstring.splice(i - 2, 2); + if (i) + aCharstring.splice(i - 2, 2); + else + aCharstring.splice(i - 1, 1); i -= 1; break; @@ -1287,7 +1284,11 @@ CFF.prototype = { case "hsbw": var charWidthVector = aCharstring[i - 1]; var leftSidebearing = aCharstring[i - 2]; - aCharstring.splice(i - 2, 3, charWidthVector, leftSidebearing, "hmoveto"); + + if (leftSidebearing) + aCharstring.splice(i - 2, 3, charWidthVector, leftSidebearing, "hmoveto"); + else + aCharstring.splice(i - 2, 3, charWidthVector); break; case "endchar": @@ -1345,7 +1346,7 @@ CFF.prototype = { var charstring = charstrings[i].charstring.slice(); var glyph = charstrings[i].glyph; - var flattened = this.flattenCharstring(charstring, aFontInfo.subrs); + var flattened = this.flattenCharstring(glyph, charstring, aFontInfo.subrs); glyphs.push(flattened); charstringsCount++; charstringsDataLength += flattened.length; From 4db56c5c97563adb9da6917f9eaf9230b69b2f3c Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Fri, 17 Jun 2011 00:37:15 +0800 Subject: [PATCH 72/77] add blogs and twitter link --- README | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README b/README index 18817c340..ee537f0a5 100644 --- a/README +++ b/README @@ -1,3 +1,12 @@ pdf.js is a technology demonstrator prototype to explore whether the HTML5 platform is complete enough to faithfully and efficiently render the ISO 32000-1:2008 Portable Document Format (PDF) without native code assistance. + +You can read more about pdf.js here: + +http://andreasgal.com/2011/06/15/pdf-js/ +http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/ + +Or follow us on twitter: @pdfjs + +http://twitter.com/#!/pdfjs From 446e958b5de4ed25d37eb2c7db5cc37afbac25dd Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Fri, 17 Jun 2011 09:11:03 +0200 Subject: [PATCH 73/77] Rename PDFFonts.js to fonts.js --- PDFFont.js => fonts.js | 0 PDFFontUtils.js => fonts_utils.js | 0 test.html | 7 +++---- 3 files changed, 3 insertions(+), 4 deletions(-) rename PDFFont.js => fonts.js (100%) rename PDFFontUtils.js => fonts_utils.js (100%) diff --git a/PDFFont.js b/fonts.js similarity index 100% rename from PDFFont.js rename to fonts.js diff --git a/PDFFontUtils.js b/fonts_utils.js similarity index 100% rename from PDFFontUtils.js rename to fonts_utils.js diff --git a/test.html b/test.html index 276ba30da..023cdeec2 100644 --- a/test.html +++ b/test.html @@ -1,15 +1,14 @@ -<<<<<<< HEAD Simple pdf.js page viewer - + + - - + From 5625a667ff3b35ae854a4cf1e2ae17fd06ea91f6 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Fri, 17 Jun 2011 00:34:03 -0700 Subject: [PATCH 74/77] store unicode value as integer instead of hex string in glyphlist --- fonts.js | 2 +- glyphlist.js | 8406 +++++++++++++++++++++++++------------------------- 2 files changed, 4204 insertions(+), 4204 deletions(-) diff --git a/fonts.js b/fonts.js index 2db7e745f..e64001155 100644 --- a/fonts.js +++ b/fonts.js @@ -40,7 +40,7 @@ var Fonts = { unicodeFromCode: function fonts_unicodeFromCode(aCode) { var unicode = GlyphsUnicode[this.active.encoding[aCode]]; - return unicode ? "0x" + unicode : aCode; + return unicode ? unicode : aCode; } }; diff --git a/glyphlist.js b/glyphlist.js index e147f6c8a..f5a11b522 100644 --- a/glyphlist.js +++ b/glyphlist.js @@ -1,1510 +1,1510 @@ var GlyphsUnicode = { - A: "0041", - AE: "00C6", - AEacute: "01FC", - AEmacron: "01E2", - AEsmall: "F7E6", - Aacute: "00C1", - Aacutesmall: "F7E1", - Abreve: "0102", - Abreveacute: "1EAE", - Abrevecyrillic: "04D0", - Abrevedotbelow: "1EB6", - Abrevegrave: "1EB0", - Abrevehookabove: "1EB2", - Abrevetilde: "1EB4", - Acaron: "01CD", - Acircle: "24B6", - Acircumflex: "00C2", - Acircumflexacute: "1EA4", - Acircumflexdotbelow: "1EAC", - Acircumflexgrave: "1EA6", - Acircumflexhookabove: "1EA8", - Acircumflexsmall: "F7E2", - Acircumflextilde: "1EAA", - Acute: "F6C9", - Acutesmall: "F7B4", - Acyrillic: "0410", - Adblgrave: "0200", - Adieresis: "00C4", - Adieresiscyrillic: "04D2", - Adieresismacron: "01DE", - Adieresissmall: "F7E4", - Adotbelow: "1EA0", - Adotmacron: "01E0", - Agrave: "00C0", - Agravesmall: "F7E0", - Ahookabove: "1EA2", - Aiecyrillic: "04D4", - Ainvertedbreve: "0202", - Alpha: "0391", - Alphatonos: "0386", - Amacron: "0100", - Amonospace: "FF21", - Aogonek: "0104", - Aring: "00C5", - Aringacute: "01FA", - Aringbelow: "1E00", - Aringsmall: "F7E5", - Asmall: "F761", - Atilde: "00C3", - Atildesmall: "F7E3", - Aybarmenian: "0531", - B: "0042", - Bcircle: "24B7", - Bdotaccent: "1E02", - Bdotbelow: "1E04", - Becyrillic: "0411", - Benarmenian: "0532", - Beta: "0392", - Bhook: "0181", - Blinebelow: "1E06", - Bmonospace: "FF22", - Brevesmall: "F6F4", - Bsmall: "F762", - Btopbar: "0182", - C: "0043", - Caarmenian: "053E", - Cacute: "0106", - Caron: "F6CA", - Caronsmall: "F6F5", - Ccaron: "010C", - Ccedilla: "00C7", - Ccedillaacute: "1E08", - Ccedillasmall: "F7E7", - Ccircle: "24B8", - Ccircumflex: "0108", - Cdot: "010A", - Cdotaccent: "010A", - Cedillasmall: "F7B8", - Chaarmenian: "0549", - Cheabkhasiancyrillic: "04BC", - Checyrillic: "0427", - Chedescenderabkhasiancyrillic: "04BE", - Chedescendercyrillic: "04B6", - Chedieresiscyrillic: "04F4", - Cheharmenian: "0543", - Chekhakassiancyrillic: "04CB", - Cheverticalstrokecyrillic: "04B8", - Chi: "03A7", - Chook: "0187", - Circumflexsmall: "F6F6", - Cmonospace: "FF23", - Coarmenian: "0551", - Csmall: "F763", - D: "0044", - DZ: "01F1", - DZcaron: "01C4", - Daarmenian: "0534", - Dafrican: "0189", - Dcaron: "010E", - Dcedilla: "1E10", - Dcircle: "24B9", - Dcircumflexbelow: "1E12", - Dcroat: "0110", - Ddotaccent: "1E0A", - Ddotbelow: "1E0C", - Decyrillic: "0414", - Deicoptic: "03EE", - Delta: "2206", - Deltagreek: "0394", - Dhook: "018A", - Dieresis: "F6CB", - DieresisAcute: "F6CC", - DieresisGrave: "F6CD", - Dieresissmall: "F7A8", - Digammagreek: "03DC", - Djecyrillic: "0402", - Dlinebelow: "1E0E", - Dmonospace: "FF24", - Dotaccentsmall: "F6F7", - Dslash: "0110", - Dsmall: "F764", - Dtopbar: "018B", - Dz: "01F2", - Dzcaron: "01C5", - Dzeabkhasiancyrillic: "04E0", - Dzecyrillic: "0405", - Dzhecyrillic: "040F", - E: "0045", - Eacute: "00C9", - Eacutesmall: "F7E9", - Ebreve: "0114", - Ecaron: "011A", - Ecedillabreve: "1E1C", - Echarmenian: "0535", - Ecircle: "24BA", - Ecircumflex: "00CA", - Ecircumflexacute: "1EBE", - Ecircumflexbelow: "1E18", - Ecircumflexdotbelow: "1EC6", - Ecircumflexgrave: "1EC0", - Ecircumflexhookabove: "1EC2", - Ecircumflexsmall: "F7EA", - Ecircumflextilde: "1EC4", - Ecyrillic: "0404", - Edblgrave: "0204", - Edieresis: "00CB", - Edieresissmall: "F7EB", - Edot: "0116", - Edotaccent: "0116", - Edotbelow: "1EB8", - Efcyrillic: "0424", - Egrave: "00C8", - Egravesmall: "F7E8", - Eharmenian: "0537", - Ehookabove: "1EBA", - Eightroman: "2167", - Einvertedbreve: "0206", - Eiotifiedcyrillic: "0464", - Elcyrillic: "041B", - Elevenroman: "216A", - Emacron: "0112", - Emacronacute: "1E16", - Emacrongrave: "1E14", - Emcyrillic: "041C", - Emonospace: "FF25", - Encyrillic: "041D", - Endescendercyrillic: "04A2", - Eng: "014A", - Enghecyrillic: "04A4", - Enhookcyrillic: "04C7", - Eogonek: "0118", - Eopen: "0190", - Epsilon: "0395", - Epsilontonos: "0388", - Ercyrillic: "0420", - Ereversed: "018E", - Ereversedcyrillic: "042D", - Escyrillic: "0421", - Esdescendercyrillic: "04AA", - Esh: "01A9", - Esmall: "F765", - Eta: "0397", - Etarmenian: "0538", - Etatonos: "0389", - Eth: "00D0", - Ethsmall: "F7F0", - Etilde: "1EBC", - Etildebelow: "1E1A", - Euro: "20AC", - Ezh: "01B7", - Ezhcaron: "01EE", - Ezhreversed: "01B8", - F: "0046", - Fcircle: "24BB", - Fdotaccent: "1E1E", - Feharmenian: "0556", - Feicoptic: "03E4", - Fhook: "0191", - Fitacyrillic: "0472", - Fiveroman: "2164", - Fmonospace: "FF26", - Fourroman: "2163", - Fsmall: "F766", - G: "0047", - GBsquare: "3387", - Gacute: "01F4", - Gamma: "0393", - Gammaafrican: "0194", - Gangiacoptic: "03EA", - Gbreve: "011E", - Gcaron: "01E6", - Gcedilla: "0122", - Gcircle: "24BC", - Gcircumflex: "011C", - Gcommaaccent: "0122", - Gdot: "0120", - Gdotaccent: "0120", - Gecyrillic: "0413", - Ghadarmenian: "0542", - Ghemiddlehookcyrillic: "0494", - Ghestrokecyrillic: "0492", - Gheupturncyrillic: "0490", - Ghook: "0193", - Gimarmenian: "0533", - Gjecyrillic: "0403", - Gmacron: "1E20", - Gmonospace: "FF27", - Grave: "F6CE", - Gravesmall: "F760", - Gsmall: "F767", - Gsmallhook: "029B", - Gstroke: "01E4", - H: "0048", - H18533: "25CF", - H18543: "25AA", - H18551: "25AB", - H22073: "25A1", - HPsquare: "33CB", - Haabkhasiancyrillic: "04A8", - Hadescendercyrillic: "04B2", - Hardsigncyrillic: "042A", - Hbar: "0126", - Hbrevebelow: "1E2A", - Hcedilla: "1E28", - Hcircle: "24BD", - Hcircumflex: "0124", - Hdieresis: "1E26", - Hdotaccent: "1E22", - Hdotbelow: "1E24", - Hmonospace: "FF28", - Hoarmenian: "0540", - Horicoptic: "03E8", - Hsmall: "F768", - Hungarumlaut: "F6CF", - Hungarumlautsmall: "F6F8", - Hzsquare: "3390", - I: "0049", - IAcyrillic: "042F", - IJ: "0132", - IUcyrillic: "042E", - Iacute: "00CD", - Iacutesmall: "F7ED", - Ibreve: "012C", - Icaron: "01CF", - Icircle: "24BE", - Icircumflex: "00CE", - Icircumflexsmall: "F7EE", - Icyrillic: "0406", - Idblgrave: "0208", - Idieresis: "00CF", - Idieresisacute: "1E2E", - Idieresiscyrillic: "04E4", - Idieresissmall: "F7EF", - Idot: "0130", - Idotaccent: "0130", - Idotbelow: "1ECA", - Iebrevecyrillic: "04D6", - Iecyrillic: "0415", - Ifraktur: "2111", - Igrave: "00CC", - Igravesmall: "F7EC", - Ihookabove: "1EC8", - Iicyrillic: "0418", - Iinvertedbreve: "020A", - Iishortcyrillic: "0419", - Imacron: "012A", - Imacroncyrillic: "04E2", - Imonospace: "FF29", - Iniarmenian: "053B", - Iocyrillic: "0401", - Iogonek: "012E", - Iota: "0399", - Iotaafrican: "0196", - Iotadieresis: "03AA", - Iotatonos: "038A", - Ismall: "F769", - Istroke: "0197", - Itilde: "0128", - Itildebelow: "1E2C", - Izhitsacyrillic: "0474", - Izhitsadblgravecyrillic: "0476", - J: "004A", - Jaarmenian: "0541", - Jcircle: "24BF", - Jcircumflex: "0134", - Jecyrillic: "0408", - Jheharmenian: "054B", - Jmonospace: "FF2A", - Jsmall: "F76A", - K: "004B", - KBsquare: "3385", - KKsquare: "33CD", - Kabashkircyrillic: "04A0", - Kacute: "1E30", - Kacyrillic: "041A", - Kadescendercyrillic: "049A", - Kahookcyrillic: "04C3", - Kappa: "039A", - Kastrokecyrillic: "049E", - Kaverticalstrokecyrillic: "049C", - Kcaron: "01E8", - Kcedilla: "0136", - Kcircle: "24C0", - Kcommaaccent: "0136", - Kdotbelow: "1E32", - Keharmenian: "0554", - Kenarmenian: "053F", - Khacyrillic: "0425", - Kheicoptic: "03E6", - Khook: "0198", - Kjecyrillic: "040C", - Klinebelow: "1E34", - Kmonospace: "FF2B", - Koppacyrillic: "0480", - Koppagreek: "03DE", - Ksicyrillic: "046E", - Ksmall: "F76B", - L: "004C", - LJ: "01C7", - LL: "F6BF", - Lacute: "0139", - Lambda: "039B", - Lcaron: "013D", - Lcedilla: "013B", - Lcircle: "24C1", - Lcircumflexbelow: "1E3C", - Lcommaaccent: "013B", - Ldot: "013F", - Ldotaccent: "013F", - Ldotbelow: "1E36", - Ldotbelowmacron: "1E38", - Liwnarmenian: "053C", - Lj: "01C8", - Ljecyrillic: "0409", - Llinebelow: "1E3A", - Lmonospace: "FF2C", - Lslash: "0141", - Lslashsmall: "F6F9", - Lsmall: "F76C", - M: "004D", - MBsquare: "3386", - Macron: "F6D0", - Macronsmall: "F7AF", - Macute: "1E3E", - Mcircle: "24C2", - Mdotaccent: "1E40", - Mdotbelow: "1E42", - Menarmenian: "0544", - Mmonospace: "FF2D", - Msmall: "F76D", - Mturned: "019C", - Mu: "039C", - N: "004E", - NJ: "01CA", - Nacute: "0143", - Ncaron: "0147", - Ncedilla: "0145", - Ncircle: "24C3", - Ncircumflexbelow: "1E4A", - Ncommaaccent: "0145", - Ndotaccent: "1E44", - Ndotbelow: "1E46", - Nhookleft: "019D", - Nineroman: "2168", - Nj: "01CB", - Njecyrillic: "040A", - Nlinebelow: "1E48", - Nmonospace: "FF2E", - Nowarmenian: "0546", - Nsmall: "F76E", - Ntilde: "00D1", - Ntildesmall: "F7F1", - Nu: "039D", - O: "004F", - OE: "0152", - OEsmall: "F6FA", - Oacute: "00D3", - Oacutesmall: "F7F3", - Obarredcyrillic: "04E8", - Obarreddieresiscyrillic: "04EA", - Obreve: "014E", - Ocaron: "01D1", - Ocenteredtilde: "019F", - Ocircle: "24C4", - Ocircumflex: "00D4", - Ocircumflexacute: "1ED0", - Ocircumflexdotbelow: "1ED8", - Ocircumflexgrave: "1ED2", - Ocircumflexhookabove: "1ED4", - Ocircumflexsmall: "F7F4", - Ocircumflextilde: "1ED6", - Ocyrillic: "041E", - Odblacute: "0150", - Odblgrave: "020C", - Odieresis: "00D6", - Odieresiscyrillic: "04E6", - Odieresissmall: "F7F6", - Odotbelow: "1ECC", - Ogoneksmall: "F6FB", - Ograve: "00D2", - Ogravesmall: "F7F2", - Oharmenian: "0555", - Ohm: "2126", - Ohookabove: "1ECE", - Ohorn: "01A0", - Ohornacute: "1EDA", - Ohorndotbelow: "1EE2", - Ohorngrave: "1EDC", - Ohornhookabove: "1EDE", - Ohorntilde: "1EE0", - Ohungarumlaut: "0150", - Oi: "01A2", - Oinvertedbreve: "020E", - Omacron: "014C", - Omacronacute: "1E52", - Omacrongrave: "1E50", - Omega: "2126", - Omegacyrillic: "0460", - Omegagreek: "03A9", - Omegaroundcyrillic: "047A", - Omegatitlocyrillic: "047C", - Omegatonos: "038F", - Omicron: "039F", - Omicrontonos: "038C", - Omonospace: "FF2F", - Oneroman: "2160", - Oogonek: "01EA", - Oogonekmacron: "01EC", - Oopen: "0186", - Oslash: "00D8", - Oslashacute: "01FE", - Oslashsmall: "F7F8", - Osmall: "F76F", - Ostrokeacute: "01FE", - Otcyrillic: "047E", - Otilde: "00D5", - Otildeacute: "1E4C", - Otildedieresis: "1E4E", - Otildesmall: "F7F5", - P: "0050", - Pacute: "1E54", - Pcircle: "24C5", - Pdotaccent: "1E56", - Pecyrillic: "041F", - Peharmenian: "054A", - Pemiddlehookcyrillic: "04A6", - Phi: "03A6", - Phook: "01A4", - Pi: "03A0", - Piwrarmenian: "0553", - Pmonospace: "FF30", - Psi: "03A8", - Psicyrillic: "0470", - Psmall: "F770", - Q: "0051", - Qcircle: "24C6", - Qmonospace: "FF31", - Qsmall: "F771", - R: "0052", - Raarmenian: "054C", - Racute: "0154", - Rcaron: "0158", - Rcedilla: "0156", - Rcircle: "24C7", - Rcommaaccent: "0156", - Rdblgrave: "0210", - Rdotaccent: "1E58", - Rdotbelow: "1E5A", - Rdotbelowmacron: "1E5C", - Reharmenian: "0550", - Rfraktur: "211C", - Rho: "03A1", - Ringsmall: "F6FC", - Rinvertedbreve: "0212", - Rlinebelow: "1E5E", - Rmonospace: "FF32", - Rsmall: "F772", - Rsmallinverted: "0281", - Rsmallinvertedsuperior: "02B6", - S: "0053", - SF010000: "250C", - SF020000: "2514", - SF030000: "2510", - SF040000: "2518", - SF050000: "253C", - SF060000: "252C", - SF070000: "2534", - SF080000: "251C", - SF090000: "2524", - SF100000: "2500", - SF110000: "2502", - SF190000: "2561", - SF200000: "2562", - SF210000: "2556", - SF220000: "2555", - SF230000: "2563", - SF240000: "2551", - SF250000: "2557", - SF260000: "255D", - SF270000: "255C", - SF280000: "255B", - SF360000: "255E", - SF370000: "255F", - SF380000: "255A", - SF390000: "2554", - SF400000: "2569", - SF410000: "2566", - SF420000: "2560", - SF430000: "2550", - SF440000: "256C", - SF450000: "2567", - SF460000: "2568", - SF470000: "2564", - SF480000: "2565", - SF490000: "2559", - SF500000: "2558", - SF510000: "2552", - SF520000: "2553", - SF530000: "256B", - SF540000: "256A", - Sacute: "015A", - Sacutedotaccent: "1E64", - Sampigreek: "03E0", - Scaron: "0160", - Scarondotaccent: "1E66", - Scaronsmall: "F6FD", - Scedilla: "015E", - Schwa: "018F", - Schwacyrillic: "04D8", - Schwadieresiscyrillic: "04DA", - Scircle: "24C8", - Scircumflex: "015C", - Scommaaccent: "0218", - Sdotaccent: "1E60", - Sdotbelow: "1E62", - Sdotbelowdotaccent: "1E68", - Seharmenian: "054D", - Sevenroman: "2166", - Shaarmenian: "0547", - Shacyrillic: "0428", - Shchacyrillic: "0429", - Sheicoptic: "03E2", - Shhacyrillic: "04BA", - Shimacoptic: "03EC", - Sigma: "03A3", - Sixroman: "2165", - Smonospace: "FF33", - Softsigncyrillic: "042C", - Ssmall: "F773", - Stigmagreek: "03DA", - T: "0054", - Tau: "03A4", - Tbar: "0166", - Tcaron: "0164", - Tcedilla: "0162", - Tcircle: "24C9", - Tcircumflexbelow: "1E70", - Tcommaaccent: "0162", - Tdotaccent: "1E6A", - Tdotbelow: "1E6C", - Tecyrillic: "0422", - Tedescendercyrillic: "04AC", - Tenroman: "2169", - Tetsecyrillic: "04B4", - Theta: "0398", - Thook: "01AC", - Thorn: "00DE", - Thornsmall: "F7FE", - Threeroman: "2162", - Tildesmall: "F6FE", - Tiwnarmenian: "054F", - Tlinebelow: "1E6E", - Tmonospace: "FF34", - Toarmenian: "0539", - Tonefive: "01BC", - Tonesix: "0184", - Tonetwo: "01A7", - Tretroflexhook: "01AE", - Tsecyrillic: "0426", - Tshecyrillic: "040B", - Tsmall: "F774", - Twelveroman: "216B", - Tworoman: "2161", - U: "0055", - Uacute: "00DA", - Uacutesmall: "F7FA", - Ubreve: "016C", - Ucaron: "01D3", - Ucircle: "24CA", - Ucircumflex: "00DB", - Ucircumflexbelow: "1E76", - Ucircumflexsmall: "F7FB", - Ucyrillic: "0423", - Udblacute: "0170", - Udblgrave: "0214", - Udieresis: "00DC", - Udieresisacute: "01D7", - Udieresisbelow: "1E72", - Udieresiscaron: "01D9", - Udieresiscyrillic: "04F0", - Udieresisgrave: "01DB", - Udieresismacron: "01D5", - Udieresissmall: "F7FC", - Udotbelow: "1EE4", - Ugrave: "00D9", - Ugravesmall: "F7F9", - Uhookabove: "1EE6", - Uhorn: "01AF", - Uhornacute: "1EE8", - Uhorndotbelow: "1EF0", - Uhorngrave: "1EEA", - Uhornhookabove: "1EEC", - Uhorntilde: "1EEE", - Uhungarumlaut: "0170", - Uhungarumlautcyrillic: "04F2", - Uinvertedbreve: "0216", - Ukcyrillic: "0478", - Umacron: "016A", - Umacroncyrillic: "04EE", - Umacrondieresis: "1E7A", - Umonospace: "FF35", - Uogonek: "0172", - Upsilon: "03A5", - Upsilon1: "03D2", - Upsilonacutehooksymbolgreek: "03D3", - Upsilonafrican: "01B1", - Upsilondieresis: "03AB", - Upsilondieresishooksymbolgreek: "03D4", - Upsilonhooksymbol: "03D2", - Upsilontonos: "038E", - Uring: "016E", - Ushortcyrillic: "040E", - Usmall: "F775", - Ustraightcyrillic: "04AE", - Ustraightstrokecyrillic: "04B0", - Utilde: "0168", - Utildeacute: "1E78", - Utildebelow: "1E74", - V: "0056", - Vcircle: "24CB", - Vdotbelow: "1E7E", - Vecyrillic: "0412", - Vewarmenian: "054E", - Vhook: "01B2", - Vmonospace: "FF36", - Voarmenian: "0548", - Vsmall: "F776", - Vtilde: "1E7C", - W: "0057", - Wacute: "1E82", - Wcircle: "24CC", - Wcircumflex: "0174", - Wdieresis: "1E84", - Wdotaccent: "1E86", - Wdotbelow: "1E88", - Wgrave: "1E80", - Wmonospace: "FF37", - Wsmall: "F777", - X: "0058", - Xcircle: "24CD", - Xdieresis: "1E8C", - Xdotaccent: "1E8A", - Xeharmenian: "053D", - Xi: "039E", - Xmonospace: "FF38", - Xsmall: "F778", - Y: "0059", - Yacute: "00DD", - Yacutesmall: "F7FD", - Yatcyrillic: "0462", - Ycircle: "24CE", - Ycircumflex: "0176", - Ydieresis: "0178", - Ydieresissmall: "F7FF", - Ydotaccent: "1E8E", - Ydotbelow: "1EF4", - Yericyrillic: "042B", - Yerudieresiscyrillic: "04F8", - Ygrave: "1EF2", - Yhook: "01B3", - Yhookabove: "1EF6", - Yiarmenian: "0545", - Yicyrillic: "0407", - Yiwnarmenian: "0552", - Ymonospace: "FF39", - Ysmall: "F779", - Ytilde: "1EF8", - Yusbigcyrillic: "046A", - Yusbigiotifiedcyrillic: "046C", - Yuslittlecyrillic: "0466", - Yuslittleiotifiedcyrillic: "0468", - Z: "005A", - Zaarmenian: "0536", - Zacute: "0179", - Zcaron: "017D", - Zcaronsmall: "F6FF", - Zcircle: "24CF", - Zcircumflex: "1E90", - Zdot: "017B", - Zdotaccent: "017B", - Zdotbelow: "1E92", - Zecyrillic: "0417", - Zedescendercyrillic: "0498", - Zedieresiscyrillic: "04DE", - Zeta: "0396", - Zhearmenian: "053A", - Zhebrevecyrillic: "04C1", - Zhecyrillic: "0416", - Zhedescendercyrillic: "0496", - Zhedieresiscyrillic: "04DC", - Zlinebelow: "1E94", - Zmonospace: "FF3A", - Zsmall: "F77A", - Zstroke: "01B5", - a: "0061", - aabengali: "0986", - aacute: "00E1", - aadeva: "0906", - aagujarati: "0A86", - aagurmukhi: "0A06", - aamatragurmukhi: "0A3E", - aarusquare: "3303", - aavowelsignbengali: "09BE", - aavowelsigndeva: "093E", - aavowelsigngujarati: "0ABE", - abbreviationmarkarmenian: "055F", - abbreviationsigndeva: "0970", - abengali: "0985", - abopomofo: "311A", - abreve: "0103", - abreveacute: "1EAF", - abrevecyrillic: "04D1", - abrevedotbelow: "1EB7", - abrevegrave: "1EB1", - abrevehookabove: "1EB3", - abrevetilde: "1EB5", - acaron: "01CE", - acircle: "24D0", - acircumflex: "00E2", - acircumflexacute: "1EA5", - acircumflexdotbelow: "1EAD", - acircumflexgrave: "1EA7", - acircumflexhookabove: "1EA9", - acircumflextilde: "1EAB", - acute: "00B4", - acutebelowcmb: "0317", - acutecmb: "0301", - acutecomb: "0301", - acutedeva: "0954", - acutelowmod: "02CF", - acutetonecmb: "0341", - acyrillic: "0430", - adblgrave: "0201", - addakgurmukhi: "0A71", - adeva: "0905", - adieresis: "00E4", - adieresiscyrillic: "04D3", - adieresismacron: "01DF", - adotbelow: "1EA1", - adotmacron: "01E1", - ae: "00E6", - aeacute: "01FD", - aekorean: "3150", - aemacron: "01E3", - afii00208: "2015", - afii08941: "20A4", - afii10017: "0410", - afii10018: "0411", - afii10019: "0412", - afii10020: "0413", - afii10021: "0414", - afii10022: "0415", - afii10023: "0401", - afii10024: "0416", - afii10025: "0417", - afii10026: "0418", - afii10027: "0419", - afii10028: "041A", - afii10029: "041B", - afii10030: "041C", - afii10031: "041D", - afii10032: "041E", - afii10033: "041F", - afii10034: "0420", - afii10035: "0421", - afii10036: "0422", - afii10037: "0423", - afii10038: "0424", - afii10039: "0425", - afii10040: "0426", - afii10041: "0427", - afii10042: "0428", - afii10043: "0429", - afii10044: "042A", - afii10045: "042B", - afii10046: "042C", - afii10047: "042D", - afii10048: "042E", - afii10049: "042F", - afii10050: "0490", - afii10051: "0402", - afii10052: "0403", - afii10053: "0404", - afii10054: "0405", - afii10055: "0406", - afii10056: "0407", - afii10057: "0408", - afii10058: "0409", - afii10059: "040A", - afii10060: "040B", - afii10061: "040C", - afii10062: "040E", - afii10063: "F6C4", - afii10064: "F6C5", - afii10065: "0430", - afii10066: "0431", - afii10067: "0432", - afii10068: "0433", - afii10069: "0434", - afii10070: "0435", - afii10071: "0451", - afii10072: "0436", - afii10073: "0437", - afii10074: "0438", - afii10075: "0439", - afii10076: "043A", - afii10077: "043B", - afii10078: "043C", - afii10079: "043D", - afii10080: "043E", - afii10081: "043F", - afii10082: "0440", - afii10083: "0441", - afii10084: "0442", - afii10085: "0443", - afii10086: "0444", - afii10087: "0445", - afii10088: "0446", - afii10089: "0447", - afii10090: "0448", - afii10091: "0449", - afii10092: "044A", - afii10093: "044B", - afii10094: "044C", - afii10095: "044D", - afii10096: "044E", - afii10097: "044F", - afii10098: "0491", - afii10099: "0452", - afii10100: "0453", - afii10101: "0454", - afii10102: "0455", - afii10103: "0456", - afii10104: "0457", - afii10105: "0458", - afii10106: "0459", - afii10107: "045A", - afii10108: "045B", - afii10109: "045C", - afii10110: "045E", - afii10145: "040F", - afii10146: "0462", - afii10147: "0472", - afii10148: "0474", - afii10192: "F6C6", - afii10193: "045F", - afii10194: "0463", - afii10195: "0473", - afii10196: "0475", - afii10831: "F6C7", - afii10832: "F6C8", - afii10846: "04D9", - afii299: "200E", - afii300: "200F", - afii301: "200D", - afii57381: "066A", - afii57388: "060C", - afii57392: "0660", - afii57393: "0661", - afii57394: "0662", - afii57395: "0663", - afii57396: "0664", - afii57397: "0665", - afii57398: "0666", - afii57399: "0667", - afii57400: "0668", - afii57401: "0669", - afii57403: "061B", - afii57407: "061F", - afii57409: "0621", - afii57410: "0622", - afii57411: "0623", - afii57412: "0624", - afii57413: "0625", - afii57414: "0626", - afii57415: "0627", - afii57416: "0628", - afii57417: "0629", - afii57418: "062A", - afii57419: "062B", - afii57420: "062C", - afii57421: "062D", - afii57422: "062E", - afii57423: "062F", - afii57424: "0630", - afii57425: "0631", - afii57426: "0632", - afii57427: "0633", - afii57428: "0634", - afii57429: "0635", - afii57430: "0636", - afii57431: "0637", - afii57432: "0638", - afii57433: "0639", - afii57434: "063A", - afii57440: "0640", - afii57441: "0641", - afii57442: "0642", - afii57443: "0643", - afii57444: "0644", - afii57445: "0645", - afii57446: "0646", - afii57448: "0648", - afii57449: "0649", - afii57450: "064A", - afii57451: "064B", - afii57452: "064C", - afii57453: "064D", - afii57454: "064E", - afii57455: "064F", - afii57456: "0650", - afii57457: "0651", - afii57458: "0652", - afii57470: "0647", - afii57505: "06A4", - afii57506: "067E", - afii57507: "0686", - afii57508: "0698", - afii57509: "06AF", - afii57511: "0679", - afii57512: "0688", - afii57513: "0691", - afii57514: "06BA", - afii57519: "06D2", - afii57534: "06D5", - afii57636: "20AA", - afii57645: "05BE", - afii57658: "05C3", - afii57664: "05D0", - afii57665: "05D1", - afii57666: "05D2", - afii57667: "05D3", - afii57668: "05D4", - afii57669: "05D5", - afii57670: "05D6", - afii57671: "05D7", - afii57672: "05D8", - afii57673: "05D9", - afii57674: "05DA", - afii57675: "05DB", - afii57676: "05DC", - afii57677: "05DD", - afii57678: "05DE", - afii57679: "05DF", - afii57680: "05E0", - afii57681: "05E1", - afii57682: "05E2", - afii57683: "05E3", - afii57684: "05E4", - afii57685: "05E5", - afii57686: "05E6", - afii57687: "05E7", - afii57688: "05E8", - afii57689: "05E9", - afii57690: "05EA", - afii57694: "FB2A", - afii57695: "FB2B", - afii57700: "FB4B", - afii57705: "FB1F", - afii57716: "05F0", - afii57717: "05F1", - afii57718: "05F2", - afii57723: "FB35", - afii57793: "05B4", - afii57794: "05B5", - afii57795: "05B6", - afii57796: "05BB", - afii57797: "05B8", - afii57798: "05B7", - afii57799: "05B0", - afii57800: "05B2", - afii57801: "05B1", - afii57802: "05B3", - afii57803: "05C2", - afii57804: "05C1", - afii57806: "05B9", - afii57807: "05BC", - afii57839: "05BD", - afii57841: "05BF", - afii57842: "05C0", - afii57929: "02BC", - afii61248: "2105", - afii61289: "2113", - afii61352: "2116", - afii61573: "202C", - afii61574: "202D", - afii61575: "202E", - afii61664: "200C", - afii63167: "066D", - afii64937: "02BD", - agrave: "00E0", - agujarati: "0A85", - agurmukhi: "0A05", - ahiragana: "3042", - ahookabove: "1EA3", - aibengali: "0990", - aibopomofo: "311E", - aideva: "0910", - aiecyrillic: "04D5", - aigujarati: "0A90", - aigurmukhi: "0A10", - aimatragurmukhi: "0A48", - ainarabic: "0639", - ainfinalarabic: "FECA", - aininitialarabic: "FECB", - ainmedialarabic: "FECC", - ainvertedbreve: "0203", - aivowelsignbengali: "09C8", - aivowelsigndeva: "0948", - aivowelsigngujarati: "0AC8", - akatakana: "30A2", - akatakanahalfwidth: "FF71", - akorean: "314F", - alef: "05D0", - alefarabic: "0627", - alefdageshhebrew: "FB30", - aleffinalarabic: "FE8E", - alefhamzaabovearabic: "0623", - alefhamzaabovefinalarabic: "FE84", - alefhamzabelowarabic: "0625", - alefhamzabelowfinalarabic: "FE88", - alefhebrew: "05D0", - aleflamedhebrew: "FB4F", - alefmaddaabovearabic: "0622", - alefmaddaabovefinalarabic: "FE82", - alefmaksuraarabic: "0649", - alefmaksurafinalarabic: "FEF0", - alefmaksurainitialarabic: "FEF3", - alefmaksuramedialarabic: "FEF4", - alefpatahhebrew: "FB2E", - alefqamatshebrew: "FB2F", - aleph: "2135", - allequal: "224C", - alpha: "03B1", - alphatonos: "03AC", - amacron: "0101", - amonospace: "FF41", - ampersand: "0026", - ampersandmonospace: "FF06", - ampersandsmall: "F726", - amsquare: "33C2", - anbopomofo: "3122", - angbopomofo: "3124", - angkhankhuthai: "0E5A", - angle: "2220", - anglebracketleft: "3008", - anglebracketleftvertical: "FE3F", - anglebracketright: "3009", - anglebracketrightvertical: "FE40", - angleleft: "2329", - angleright: "232A", - angstrom: "212B", - anoteleia: "0387", - anudattadeva: "0952", - anusvarabengali: "0982", - anusvaradeva: "0902", - anusvaragujarati: "0A82", - aogonek: "0105", - apaatosquare: "3300", - aparen: "249C", - apostrophearmenian: "055A", - apostrophemod: "02BC", - apple: "F8FF", - approaches: "2250", - approxequal: "2248", - approxequalorimage: "2252", - approximatelyequal: "2245", - araeaekorean: "318E", - araeakorean: "318D", - arc: "2312", - arighthalfring: "1E9A", - aring: "00E5", - aringacute: "01FB", - aringbelow: "1E01", - arrowboth: "2194", - arrowdashdown: "21E3", - arrowdashleft: "21E0", - arrowdashright: "21E2", - arrowdashup: "21E1", - arrowdblboth: "21D4", - arrowdbldown: "21D3", - arrowdblleft: "21D0", - arrowdblright: "21D2", - arrowdblup: "21D1", - arrowdown: "2193", - arrowdownleft: "2199", - arrowdownright: "2198", - arrowdownwhite: "21E9", - arrowheaddownmod: "02C5", - arrowheadleftmod: "02C2", - arrowheadrightmod: "02C3", - arrowheadupmod: "02C4", - arrowhorizex: "F8E7", - arrowleft: "2190", - arrowleftdbl: "21D0", - arrowleftdblstroke: "21CD", - arrowleftoverright: "21C6", - arrowleftwhite: "21E6", - arrowright: "2192", - arrowrightdblstroke: "21CF", - arrowrightheavy: "279E", - arrowrightoverleft: "21C4", - arrowrightwhite: "21E8", - arrowtableft: "21E4", - arrowtabright: "21E5", - arrowup: "2191", - arrowupdn: "2195", - arrowupdnbse: "21A8", - arrowupdownbase: "21A8", - arrowupleft: "2196", - arrowupleftofdown: "21C5", - arrowupright: "2197", - arrowupwhite: "21E7", - arrowvertex: "F8E6", - asciicircum: "005E", - asciicircummonospace: "FF3E", - asciitilde: "007E", - asciitildemonospace: "FF5E", - ascript: "0251", - ascriptturned: "0252", - asmallhiragana: "3041", - asmallkatakana: "30A1", - asmallkatakanahalfwidth: "FF67", - asterisk: "002A", - asteriskaltonearabic: "066D", - asteriskarabic: "066D", - asteriskmath: "2217", - asteriskmonospace: "FF0A", - asterisksmall: "FE61", - asterism: "2042", - asuperior: "F6E9", - asymptoticallyequal: "2243", - at: "0040", - atilde: "00E3", - atmonospace: "FF20", - atsmall: "FE6B", - aturned: "0250", - aubengali: "0994", - aubopomofo: "3120", - audeva: "0914", - augujarati: "0A94", - augurmukhi: "0A14", - aulengthmarkbengali: "09D7", - aumatragurmukhi: "0A4C", - auvowelsignbengali: "09CC", - auvowelsigndeva: "094C", - auvowelsigngujarati: "0ACC", - avagrahadeva: "093D", - aybarmenian: "0561", - ayin: "05E2", - ayinaltonehebrew: "FB20", - ayinhebrew: "05E2", - b: "0062", - babengali: "09AC", - backslash: "005C", - backslashmonospace: "FF3C", - badeva: "092C", - bagujarati: "0AAC", - bagurmukhi: "0A2C", - bahiragana: "3070", - bahtthai: "0E3F", - bakatakana: "30D0", - bar: "007C", - barmonospace: "FF5C", - bbopomofo: "3105", - bcircle: "24D1", - bdotaccent: "1E03", - bdotbelow: "1E05", - beamedsixteenthnotes: "266C", - because: "2235", - becyrillic: "0431", - beharabic: "0628", - behfinalarabic: "FE90", - behinitialarabic: "FE91", - behiragana: "3079", - behmedialarabic: "FE92", - behmeeminitialarabic: "FC9F", - behmeemisolatedarabic: "FC08", - behnoonfinalarabic: "FC6D", - bekatakana: "30D9", - benarmenian: "0562", - bet: "05D1", - beta: "03B2", - betasymbolgreek: "03D0", - betdagesh: "FB31", - betdageshhebrew: "FB31", - bethebrew: "05D1", - betrafehebrew: "FB4C", - bhabengali: "09AD", - bhadeva: "092D", - bhagujarati: "0AAD", - bhagurmukhi: "0A2D", - bhook: "0253", - bihiragana: "3073", - bikatakana: "30D3", - bilabialclick: "0298", - bindigurmukhi: "0A02", - birusquare: "3331", - blackcircle: "25CF", - blackdiamond: "25C6", - blackdownpointingtriangle: "25BC", - blackleftpointingpointer: "25C4", - blackleftpointingtriangle: "25C0", - blacklenticularbracketleft: "3010", - blacklenticularbracketleftvertical: "FE3B", - blacklenticularbracketright: "3011", - blacklenticularbracketrightvertical: "FE3C", - blacklowerlefttriangle: "25E3", - blacklowerrighttriangle: "25E2", - blackrectangle: "25AC", - blackrightpointingpointer: "25BA", - blackrightpointingtriangle: "25B6", - blacksmallsquare: "25AA", - blacksmilingface: "263B", - blacksquare: "25A0", - blackstar: "2605", - blackupperlefttriangle: "25E4", - blackupperrighttriangle: "25E5", - blackuppointingsmalltriangle: "25B4", - blackuppointingtriangle: "25B2", - blank: "2423", - blinebelow: "1E07", - block: "2588", - bmonospace: "FF42", - bobaimaithai: "0E1A", - bohiragana: "307C", - bokatakana: "30DC", - bparen: "249D", - bqsquare: "33C3", - braceex: "F8F4", - braceleft: "007B", - braceleftbt: "F8F3", - braceleftmid: "F8F2", - braceleftmonospace: "FF5B", - braceleftsmall: "FE5B", - bracelefttp: "F8F1", - braceleftvertical: "FE37", - braceright: "007D", - bracerightbt: "F8FE", - bracerightmid: "F8FD", - bracerightmonospace: "FF5D", - bracerightsmall: "FE5C", - bracerighttp: "F8FC", - bracerightvertical: "FE38", - bracketleft: "005B", - bracketleftbt: "F8F0", - bracketleftex: "F8EF", - bracketleftmonospace: "FF3B", - bracketlefttp: "F8EE", - bracketright: "005D", - bracketrightbt: "F8FB", - bracketrightex: "F8FA", - bracketrightmonospace: "FF3D", - bracketrighttp: "F8F9", - breve: "02D8", - brevebelowcmb: "032E", - brevecmb: "0306", - breveinvertedbelowcmb: "032F", - breveinvertedcmb: "0311", - breveinverteddoublecmb: "0361", - bridgebelowcmb: "032A", - bridgeinvertedbelowcmb: "033A", - brokenbar: "00A6", - bstroke: "0180", - bsuperior: "F6EA", - btopbar: "0183", - buhiragana: "3076", - bukatakana: "30D6", - bullet: "2022", - bulletinverse: "25D8", - bulletoperator: "2219", - bullseye: "25CE", - c: "0063", - caarmenian: "056E", - cabengali: "099A", - cacute: "0107", - cadeva: "091A", - cagujarati: "0A9A", - cagurmukhi: "0A1A", - calsquare: "3388", - candrabindubengali: "0981", - candrabinducmb: "0310", - candrabindudeva: "0901", - candrabindugujarati: "0A81", - capslock: "21EA", - careof: "2105", - caron: "02C7", - caronbelowcmb: "032C", - caroncmb: "030C", - carriagereturn: "21B5", - cbopomofo: "3118", - ccaron: "010D", - ccedilla: "00E7", - ccedillaacute: "1E09", - ccircle: "24D2", - ccircumflex: "0109", - ccurl: "0255", - cdot: "010B", - cdotaccent: "010B", - cdsquare: "33C5", - cedilla: "00B8", - cedillacmb: "0327", - cent: "00A2", - centigrade: "2103", - centinferior: "F6DF", - centmonospace: "FFE0", - centoldstyle: "F7A2", - centsuperior: "F6E0", - chaarmenian: "0579", - chabengali: "099B", - chadeva: "091B", - chagujarati: "0A9B", - chagurmukhi: "0A1B", - chbopomofo: "3114", - cheabkhasiancyrillic: "04BD", - checkmark: "2713", - checyrillic: "0447", - chedescenderabkhasiancyrillic: "04BF", - chedescendercyrillic: "04B7", - chedieresiscyrillic: "04F5", - cheharmenian: "0573", - chekhakassiancyrillic: "04CC", - cheverticalstrokecyrillic: "04B9", - chi: "03C7", - chieuchacirclekorean: "3277", - chieuchaparenkorean: "3217", - chieuchcirclekorean: "3269", - chieuchkorean: "314A", - chieuchparenkorean: "3209", - chochangthai: "0E0A", - chochanthai: "0E08", - chochingthai: "0E09", - chochoethai: "0E0C", - chook: "0188", - cieucacirclekorean: "3276", - cieucaparenkorean: "3216", - cieuccirclekorean: "3268", - cieuckorean: "3148", - cieucparenkorean: "3208", - cieucuparenkorean: "321C", - circle: "25CB", - circlemultiply: "2297", - circleot: "2299", - circleplus: "2295", - circlepostalmark: "3036", - circlewithlefthalfblack: "25D0", - circlewithrighthalfblack: "25D1", - circumflex: "02C6", - circumflexbelowcmb: "032D", - circumflexcmb: "0302", - clear: "2327", - clickalveolar: "01C2", - clickdental: "01C0", - clicklateral: "01C1", - clickretroflex: "01C3", - club: "2663", - clubsuitblack: "2663", - clubsuitwhite: "2667", - cmcubedsquare: "33A4", - cmonospace: "FF43", - cmsquaredsquare: "33A0", - coarmenian: "0581", - colon: "003A", - colonmonetary: "20A1", - colonmonospace: "FF1A", - colonsign: "20A1", - colonsmall: "FE55", - colontriangularhalfmod: "02D1", - colontriangularmod: "02D0", - comma: "002C", - commaabovecmb: "0313", - commaaboverightcmb: "0315", - commaaccent: "F6C3", - commaarabic: "060C", - commaarmenian: "055D", - commainferior: "F6E1", - commamonospace: "FF0C", - commareversedabovecmb: "0314", - commareversedmod: "02BD", - commasmall: "FE50", - commasuperior: "F6E2", - commaturnedabovecmb: "0312", - commaturnedmod: "02BB", - compass: "263C", - congruent: "2245", - contourintegral: "222E", - control: "2303", - controlACK: "0006", - controlBEL: "0007", - controlBS: "0008", - controlCAN: "0018", - controlCR: "000D", - controlDC1: "0011", - controlDC2: "0012", - controlDC3: "0013", - controlDC4: "0014", - controlDEL: "007F", - controlDLE: "0010", - controlEM: "0019", - controlENQ: "0005", - controlEOT: "0004", - controlESC: "001B", - controlETB: "0017", - controlETX: "0003", - controlFF: "000C", - controlFS: "001C", - controlGS: "001D", - controlHT: "0009", - controlLF: "000A", - controlNAK: "0015", - controlRS: "001E", - controlSI: "000F", - controlSO: "000E", - controlSOT: "0002", - controlSTX: "0001", - controlSUB: "001A", - controlSYN: "0016", - controlUS: "001F", - controlVT: "000B", - copyright: "00A9", - copyrightsans: "F8E9", - copyrightserif: "F6D9", - cornerbracketleft: "300C", - cornerbracketlefthalfwidth: "FF62", - cornerbracketleftvertical: "FE41", - cornerbracketright: "300D", - cornerbracketrighthalfwidth: "FF63", - cornerbracketrightvertical: "FE42", - corporationsquare: "337F", - cosquare: "33C7", - coverkgsquare: "33C6", - cparen: "249E", - cruzeiro: "20A2", - cstretched: "0297", - curlyand: "22CF", - curlyor: "22CE", - currency: "00A4", - cyrBreve: "F6D1", - cyrFlex: "F6D2", - cyrbreve: "F6D4", - cyrflex: "F6D5", - d: "0064", - daarmenian: "0564", - dabengali: "09A6", - dadarabic: "0636", - dadeva: "0926", - dadfinalarabic: "FEBE", - dadinitialarabic: "FEBF", - dadmedialarabic: "FEC0", - dagesh: "05BC", - dageshhebrew: "05BC", - dagger: "2020", - daggerdbl: "2021", - dagujarati: "0AA6", - dagurmukhi: "0A26", - dahiragana: "3060", - dakatakana: "30C0", - dalarabic: "062F", - dalet: "05D3", - daletdagesh: "FB33", - daletdageshhebrew: "FB33", + 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: "05D3", + dalethebrew: 0x05D3, dalethiriq: "05D3 05B4", dalethiriqhebrew: "05D3 05B4", daletholam: "05D3 05B9", @@ -1521,1641 +1521,1641 @@ var GlyphsUnicode = { daletshevahebrew: "05D3 05B0", dalettsere: "05D3 05B5", dalettserehebrew: "05D3 05B5", - dalfinalarabic: "FEAA", - dammaarabic: "064F", - dammalowarabic: "064F", - dammatanaltonearabic: "064C", - dammatanarabic: "064C", - danda: "0964", - dargahebrew: "05A7", - dargalefthebrew: "05A7", - dasiapneumatacyrilliccmb: "0485", - dblGrave: "F6D3", - dblanglebracketleft: "300A", - dblanglebracketleftvertical: "FE3D", - dblanglebracketright: "300B", - dblanglebracketrightvertical: "FE3E", - dblarchinvertedbelowcmb: "032B", - dblarrowleft: "21D4", - dblarrowright: "21D2", - dbldanda: "0965", - dblgrave: "F6D6", - dblgravecmb: "030F", - dblintegral: "222C", - dbllowline: "2017", - dbllowlinecmb: "0333", - dbloverlinecmb: "033F", - dblprimemod: "02BA", - dblverticalbar: "2016", - dblverticallineabovecmb: "030E", - dbopomofo: "3109", - dbsquare: "33C8", - dcaron: "010F", - dcedilla: "1E11", - dcircle: "24D3", - dcircumflexbelow: "1E13", - dcroat: "0111", - ddabengali: "09A1", - ddadeva: "0921", - ddagujarati: "0AA1", - ddagurmukhi: "0A21", - ddalarabic: "0688", - ddalfinalarabic: "FB89", - dddhadeva: "095C", - ddhabengali: "09A2", - ddhadeva: "0922", - ddhagujarati: "0AA2", - ddhagurmukhi: "0A22", - ddotaccent: "1E0B", - ddotbelow: "1E0D", - decimalseparatorarabic: "066B", - decimalseparatorpersian: "066B", - decyrillic: "0434", - degree: "00B0", - dehihebrew: "05AD", - dehiragana: "3067", - deicoptic: "03EF", - dekatakana: "30C7", - deleteleft: "232B", - deleteright: "2326", - delta: "03B4", - deltaturned: "018D", - denominatorminusonenumeratorbengali: "09F8", - dezh: "02A4", - dhabengali: "09A7", - dhadeva: "0927", - dhagujarati: "0AA7", - dhagurmukhi: "0A27", - dhook: "0257", - dialytikatonos: "0385", - dialytikatonoscmb: "0344", - diamond: "2666", - diamondsuitwhite: "2662", - dieresis: "00A8", - dieresisacute: "F6D7", - dieresisbelowcmb: "0324", - dieresiscmb: "0308", - dieresisgrave: "F6D8", - dieresistonos: "0385", - dihiragana: "3062", - dikatakana: "30C2", - dittomark: "3003", - divide: "00F7", - divides: "2223", - divisionslash: "2215", - djecyrillic: "0452", - dkshade: "2593", - dlinebelow: "1E0F", - dlsquare: "3397", - dmacron: "0111", - dmonospace: "FF44", - dnblock: "2584", - dochadathai: "0E0E", - dodekthai: "0E14", - dohiragana: "3069", - dokatakana: "30C9", - dollar: "0024", - dollarinferior: "F6E3", - dollarmonospace: "FF04", - dollaroldstyle: "F724", - dollarsmall: "FE69", - dollarsuperior: "F6E4", - dong: "20AB", - dorusquare: "3326", - dotaccent: "02D9", - dotaccentcmb: "0307", - dotbelowcmb: "0323", - dotbelowcomb: "0323", - dotkatakana: "30FB", - dotlessi: "0131", - dotlessj: "F6BE", - dotlessjstrokehook: "0284", - dotmath: "22C5", - dottedcircle: "25CC", - doubleyodpatah: "FB1F", - doubleyodpatahhebrew: "FB1F", - downtackbelowcmb: "031E", - downtackmod: "02D5", - dparen: "249F", - dsuperior: "F6EB", - dtail: "0256", - dtopbar: "018C", - duhiragana: "3065", - dukatakana: "30C5", - dz: "01F3", - dzaltone: "02A3", - dzcaron: "01C6", - dzcurl: "02A5", - dzeabkhasiancyrillic: "04E1", - dzecyrillic: "0455", - dzhecyrillic: "045F", - e: "0065", - eacute: "00E9", - earth: "2641", - ebengali: "098F", - ebopomofo: "311C", - ebreve: "0115", - ecandradeva: "090D", - ecandragujarati: "0A8D", - ecandravowelsigndeva: "0945", - ecandravowelsigngujarati: "0AC5", - ecaron: "011B", - ecedillabreve: "1E1D", - echarmenian: "0565", - echyiwnarmenian: "0587", - ecircle: "24D4", - ecircumflex: "00EA", - ecircumflexacute: "1EBF", - ecircumflexbelow: "1E19", - ecircumflexdotbelow: "1EC7", - ecircumflexgrave: "1EC1", - ecircumflexhookabove: "1EC3", - ecircumflextilde: "1EC5", - ecyrillic: "0454", - edblgrave: "0205", - edeva: "090F", - edieresis: "00EB", - edot: "0117", - edotaccent: "0117", - edotbelow: "1EB9", - eegurmukhi: "0A0F", - eematragurmukhi: "0A47", - efcyrillic: "0444", - egrave: "00E8", - egujarati: "0A8F", - eharmenian: "0567", - ehbopomofo: "311D", - ehiragana: "3048", - ehookabove: "1EBB", - eibopomofo: "311F", - eight: "0038", - eightarabic: "0668", - eightbengali: "09EE", - eightcircle: "2467", - eightcircleinversesansserif: "2791", - eightdeva: "096E", - eighteencircle: "2471", - eighteenparen: "2485", - eighteenperiod: "2499", - eightgujarati: "0AEE", - eightgurmukhi: "0A6E", - eighthackarabic: "0668", - eighthangzhou: "3028", - eighthnotebeamed: "266B", - eightideographicparen: "3227", - eightinferior: "2088", - eightmonospace: "FF18", - eightoldstyle: "F738", - eightparen: "247B", - eightperiod: "248F", - eightpersian: "06F8", - eightroman: "2177", - eightsuperior: "2078", - eightthai: "0E58", - einvertedbreve: "0207", - eiotifiedcyrillic: "0465", - ekatakana: "30A8", - ekatakanahalfwidth: "FF74", - ekonkargurmukhi: "0A74", - ekorean: "3154", - elcyrillic: "043B", - element: "2208", - elevencircle: "246A", - elevenparen: "247E", - elevenperiod: "2492", - elevenroman: "217A", - ellipsis: "2026", - ellipsisvertical: "22EE", - emacron: "0113", - emacronacute: "1E17", - emacrongrave: "1E15", - emcyrillic: "043C", - emdash: "2014", - emdashvertical: "FE31", - emonospace: "FF45", - emphasismarkarmenian: "055B", - emptyset: "2205", - enbopomofo: "3123", - encyrillic: "043D", - endash: "2013", - endashvertical: "FE32", - endescendercyrillic: "04A3", - eng: "014B", - engbopomofo: "3125", - enghecyrillic: "04A5", - enhookcyrillic: "04C8", - enspace: "2002", - eogonek: "0119", - eokorean: "3153", - eopen: "025B", - eopenclosed: "029A", - eopenreversed: "025C", - eopenreversedclosed: "025E", - eopenreversedhook: "025D", - eparen: "24A0", - epsilon: "03B5", - epsilontonos: "03AD", - equal: "003D", - equalmonospace: "FF1D", - equalsmall: "FE66", - equalsuperior: "207C", - equivalence: "2261", - erbopomofo: "3126", - ercyrillic: "0440", - ereversed: "0258", - ereversedcyrillic: "044D", - escyrillic: "0441", - esdescendercyrillic: "04AB", - esh: "0283", - eshcurl: "0286", - eshortdeva: "090E", - eshortvowelsigndeva: "0946", - eshreversedloop: "01AA", - eshsquatreversed: "0285", - esmallhiragana: "3047", - esmallkatakana: "30A7", - esmallkatakanahalfwidth: "FF6A", - estimated: "212E", - esuperior: "F6EC", - eta: "03B7", - etarmenian: "0568", - etatonos: "03AE", - eth: "00F0", - etilde: "1EBD", - etildebelow: "1E1B", - etnahtafoukhhebrew: "0591", - etnahtafoukhlefthebrew: "0591", - etnahtahebrew: "0591", - etnahtalefthebrew: "0591", - eturned: "01DD", - eukorean: "3161", - euro: "20AC", - evowelsignbengali: "09C7", - evowelsigndeva: "0947", - evowelsigngujarati: "0AC7", - exclam: "0021", - exclamarmenian: "055C", - exclamdbl: "203C", - exclamdown: "00A1", - exclamdownsmall: "F7A1", - exclammonospace: "FF01", - exclamsmall: "F721", - existential: "2203", - ezh: "0292", - ezhcaron: "01EF", - ezhcurl: "0293", - ezhreversed: "01B9", - ezhtail: "01BA", - f: "0066", - fadeva: "095E", - fagurmukhi: "0A5E", - fahrenheit: "2109", - fathaarabic: "064E", - fathalowarabic: "064E", - fathatanarabic: "064B", - fbopomofo: "3108", - fcircle: "24D5", - fdotaccent: "1E1F", - feharabic: "0641", - feharmenian: "0586", - fehfinalarabic: "FED2", - fehinitialarabic: "FED3", - fehmedialarabic: "FED4", - feicoptic: "03E5", - female: "2640", - ff: "FB00", - ffi: "FB03", - ffl: "FB04", - fi: "FB01", - fifteencircle: "246E", - fifteenparen: "2482", - fifteenperiod: "2496", - figuredash: "2012", - filledbox: "25A0", - filledrect: "25AC", - finalkaf: "05DA", - finalkafdagesh: "FB3A", - finalkafdageshhebrew: "FB3A", - finalkafhebrew: "05DA", + 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: "05DD", - finalmemhebrew: "05DD", - finalnun: "05DF", - finalnunhebrew: "05DF", - finalpe: "05E3", - finalpehebrew: "05E3", - finaltsadi: "05E5", - finaltsadihebrew: "05E5", - firsttonechinese: "02C9", - fisheye: "25C9", - fitacyrillic: "0473", - five: "0035", - fivearabic: "0665", - fivebengali: "09EB", - fivecircle: "2464", - fivecircleinversesansserif: "278E", - fivedeva: "096B", - fiveeighths: "215D", - fivegujarati: "0AEB", - fivegurmukhi: "0A6B", - fivehackarabic: "0665", - fivehangzhou: "3025", - fiveideographicparen: "3224", - fiveinferior: "2085", - fivemonospace: "FF15", - fiveoldstyle: "F735", - fiveparen: "2478", - fiveperiod: "248C", - fivepersian: "06F5", - fiveroman: "2174", - fivesuperior: "2075", - fivethai: "0E55", - fl: "FB02", - florin: "0192", - fmonospace: "FF46", - fmsquare: "3399", - fofanthai: "0E1F", - fofathai: "0E1D", - fongmanthai: "0E4F", - forall: "2200", - four: "0034", - fourarabic: "0664", - fourbengali: "09EA", - fourcircle: "2463", - fourcircleinversesansserif: "278D", - fourdeva: "096A", - fourgujarati: "0AEA", - fourgurmukhi: "0A6A", - fourhackarabic: "0664", - fourhangzhou: "3024", - fourideographicparen: "3223", - fourinferior: "2084", - fourmonospace: "FF14", - fournumeratorbengali: "09F7", - fouroldstyle: "F734", - fourparen: "2477", - fourperiod: "248B", - fourpersian: "06F4", - fourroman: "2173", - foursuperior: "2074", - fourteencircle: "246D", - fourteenparen: "2481", - fourteenperiod: "2495", - fourthai: "0E54", - fourthtonechinese: "02CB", - fparen: "24A1", - fraction: "2044", - franc: "20A3", - g: "0067", - gabengali: "0997", - gacute: "01F5", - gadeva: "0917", - gafarabic: "06AF", - gaffinalarabic: "FB93", - gafinitialarabic: "FB94", - gafmedialarabic: "FB95", - gagujarati: "0A97", - gagurmukhi: "0A17", - gahiragana: "304C", - gakatakana: "30AC", - gamma: "03B3", - gammalatinsmall: "0263", - gammasuperior: "02E0", - gangiacoptic: "03EB", - gbopomofo: "310D", - gbreve: "011F", - gcaron: "01E7", - gcedilla: "0123", - gcircle: "24D6", - gcircumflex: "011D", - gcommaaccent: "0123", - gdot: "0121", - gdotaccent: "0121", - gecyrillic: "0433", - gehiragana: "3052", - gekatakana: "30B2", - geometricallyequal: "2251", - gereshaccenthebrew: "059C", - gereshhebrew: "05F3", - gereshmuqdamhebrew: "059D", - germandbls: "00DF", - gershayimaccenthebrew: "059E", - gershayimhebrew: "05F4", - getamark: "3013", - ghabengali: "0998", - ghadarmenian: "0572", - ghadeva: "0918", - ghagujarati: "0A98", - ghagurmukhi: "0A18", - ghainarabic: "063A", - ghainfinalarabic: "FECE", - ghaininitialarabic: "FECF", - ghainmedialarabic: "FED0", - ghemiddlehookcyrillic: "0495", - ghestrokecyrillic: "0493", - gheupturncyrillic: "0491", - ghhadeva: "095A", - ghhagurmukhi: "0A5A", - ghook: "0260", - ghzsquare: "3393", - gihiragana: "304E", - gikatakana: "30AE", - gimarmenian: "0563", - gimel: "05D2", - gimeldagesh: "FB32", - gimeldageshhebrew: "FB32", - gimelhebrew: "05D2", - gjecyrillic: "0453", - glottalinvertedstroke: "01BE", - glottalstop: "0294", - glottalstopinverted: "0296", - glottalstopmod: "02C0", - glottalstopreversed: "0295", - glottalstopreversedmod: "02C1", - glottalstopreversedsuperior: "02E4", - glottalstopstroke: "02A1", - glottalstopstrokereversed: "02A2", - gmacron: "1E21", - gmonospace: "FF47", - gohiragana: "3054", - gokatakana: "30B4", - gparen: "24A2", - gpasquare: "33AC", - gradient: "2207", - grave: "0060", - gravebelowcmb: "0316", - gravecmb: "0300", - gravecomb: "0300", - gravedeva: "0953", - gravelowmod: "02CE", - gravemonospace: "FF40", - gravetonecmb: "0340", - greater: "003E", - greaterequal: "2265", - greaterequalorless: "22DB", - greatermonospace: "FF1E", - greaterorequivalent: "2273", - greaterorless: "2277", - greateroverequal: "2267", - greatersmall: "FE65", - gscript: "0261", - gstroke: "01E5", - guhiragana: "3050", - guillemotleft: "00AB", - guillemotright: "00BB", - guilsinglleft: "2039", - guilsinglright: "203A", - gukatakana: "30B0", - guramusquare: "3318", - gysquare: "33C9", - h: "0068", - haabkhasiancyrillic: "04A9", - haaltonearabic: "06C1", - habengali: "09B9", - hadescendercyrillic: "04B3", - hadeva: "0939", - hagujarati: "0AB9", - hagurmukhi: "0A39", - haharabic: "062D", - hahfinalarabic: "FEA2", - hahinitialarabic: "FEA3", - hahiragana: "306F", - hahmedialarabic: "FEA4", - haitusquare: "332A", - hakatakana: "30CF", - hakatakanahalfwidth: "FF8A", - halantgurmukhi: "0A4D", - hamzaarabic: "0621", + 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: "0621", + hamzalowarabic: 0x0621, hamzalowkasraarabic: "0621 0650", hamzalowkasratanarabic: "0621 064D", hamzasukunarabic: "0621 0652", - hangulfiller: "3164", - hardsigncyrillic: "044A", - harpoonleftbarbup: "21BC", - harpoonrightbarbup: "21C0", - hasquare: "33CA", - hatafpatah: "05B2", - hatafpatah16: "05B2", - hatafpatah23: "05B2", - hatafpatah2f: "05B2", - hatafpatahhebrew: "05B2", - hatafpatahnarrowhebrew: "05B2", - hatafpatahquarterhebrew: "05B2", - hatafpatahwidehebrew: "05B2", - hatafqamats: "05B3", - hatafqamats1b: "05B3", - hatafqamats28: "05B3", - hatafqamats34: "05B3", - hatafqamatshebrew: "05B3", - hatafqamatsnarrowhebrew: "05B3", - hatafqamatsquarterhebrew: "05B3", - hatafqamatswidehebrew: "05B3", - hatafsegol: "05B1", - hatafsegol17: "05B1", - hatafsegol24: "05B1", - hatafsegol30: "05B1", - hatafsegolhebrew: "05B1", - hatafsegolnarrowhebrew: "05B1", - hatafsegolquarterhebrew: "05B1", - hatafsegolwidehebrew: "05B1", - hbar: "0127", - hbopomofo: "310F", - hbrevebelow: "1E2B", - hcedilla: "1E29", - hcircle: "24D7", - hcircumflex: "0125", - hdieresis: "1E27", - hdotaccent: "1E23", - hdotbelow: "1E25", - he: "05D4", - heart: "2665", - heartsuitblack: "2665", - heartsuitwhite: "2661", - hedagesh: "FB34", - hedageshhebrew: "FB34", - hehaltonearabic: "06C1", - heharabic: "0647", - hehebrew: "05D4", - hehfinalaltonearabic: "FBA7", - hehfinalalttwoarabic: "FEEA", - hehfinalarabic: "FEEA", - hehhamzaabovefinalarabic: "FBA5", - hehhamzaaboveisolatedarabic: "FBA4", - hehinitialaltonearabic: "FBA8", - hehinitialarabic: "FEEB", - hehiragana: "3078", - hehmedialaltonearabic: "FBA9", - hehmedialarabic: "FEEC", - heiseierasquare: "337B", - hekatakana: "30D8", - hekatakanahalfwidth: "FF8D", - hekutaarusquare: "3336", - henghook: "0267", - herutusquare: "3339", - het: "05D7", - hethebrew: "05D7", - hhook: "0266", - hhooksuperior: "02B1", - hieuhacirclekorean: "327B", - hieuhaparenkorean: "321B", - hieuhcirclekorean: "326D", - hieuhkorean: "314E", - hieuhparenkorean: "320D", - hihiragana: "3072", - hikatakana: "30D2", - hikatakanahalfwidth: "FF8B", - hiriq: "05B4", - hiriq14: "05B4", - hiriq21: "05B4", - hiriq2d: "05B4", - hiriqhebrew: "05B4", - hiriqnarrowhebrew: "05B4", - hiriqquarterhebrew: "05B4", - hiriqwidehebrew: "05B4", - hlinebelow: "1E96", - hmonospace: "FF48", - hoarmenian: "0570", - hohipthai: "0E2B", - hohiragana: "307B", - hokatakana: "30DB", - hokatakanahalfwidth: "FF8E", - holam: "05B9", - holam19: "05B9", - holam26: "05B9", - holam32: "05B9", - holamhebrew: "05B9", - holamnarrowhebrew: "05B9", - holamquarterhebrew: "05B9", - holamwidehebrew: "05B9", - honokhukthai: "0E2E", - hookabovecomb: "0309", - hookcmb: "0309", - hookpalatalizedbelowcmb: "0321", - hookretroflexbelowcmb: "0322", - hoonsquare: "3342", - horicoptic: "03E9", - horizontalbar: "2015", - horncmb: "031B", - hotsprings: "2668", - house: "2302", - hparen: "24A3", - hsuperior: "02B0", - hturned: "0265", - huhiragana: "3075", - huiitosquare: "3333", - hukatakana: "30D5", - hukatakanahalfwidth: "FF8C", - hungarumlaut: "02DD", - hungarumlautcmb: "030B", - hv: "0195", - hyphen: "002D", - hypheninferior: "F6E5", - hyphenmonospace: "FF0D", - hyphensmall: "FE63", - hyphensuperior: "F6E6", - hyphentwo: "2010", - i: "0069", - iacute: "00ED", - iacyrillic: "044F", - ibengali: "0987", - ibopomofo: "3127", - ibreve: "012D", - icaron: "01D0", - icircle: "24D8", - icircumflex: "00EE", - icyrillic: "0456", - idblgrave: "0209", - ideographearthcircle: "328F", - ideographfirecircle: "328B", - ideographicallianceparen: "323F", - ideographiccallparen: "323A", - ideographiccentrecircle: "32A5", - ideographicclose: "3006", - ideographiccomma: "3001", - ideographiccommaleft: "FF64", - ideographiccongratulationparen: "3237", - ideographiccorrectcircle: "32A3", - ideographicearthparen: "322F", - ideographicenterpriseparen: "323D", - ideographicexcellentcircle: "329D", - ideographicfestivalparen: "3240", - ideographicfinancialcircle: "3296", - ideographicfinancialparen: "3236", - ideographicfireparen: "322B", - ideographichaveparen: "3232", - ideographichighcircle: "32A4", - ideographiciterationmark: "3005", - ideographiclaborcircle: "3298", - ideographiclaborparen: "3238", - ideographicleftcircle: "32A7", - ideographiclowcircle: "32A6", - ideographicmedicinecircle: "32A9", - ideographicmetalparen: "322E", - ideographicmoonparen: "322A", - ideographicnameparen: "3234", - ideographicperiod: "3002", - ideographicprintcircle: "329E", - ideographicreachparen: "3243", - ideographicrepresentparen: "3239", - ideographicresourceparen: "323E", - ideographicrightcircle: "32A8", - ideographicsecretcircle: "3299", - ideographicselfparen: "3242", - ideographicsocietyparen: "3233", - ideographicspace: "3000", - ideographicspecialparen: "3235", - ideographicstockparen: "3231", - ideographicstudyparen: "323B", - ideographicsunparen: "3230", - ideographicsuperviseparen: "323C", - ideographicwaterparen: "322C", - ideographicwoodparen: "322D", - ideographiczero: "3007", - ideographmetalcircle: "328E", - ideographmooncircle: "328A", - ideographnamecircle: "3294", - ideographsuncircle: "3290", - ideographwatercircle: "328C", - ideographwoodcircle: "328D", - ideva: "0907", - idieresis: "00EF", - idieresisacute: "1E2F", - idieresiscyrillic: "04E5", - idotbelow: "1ECB", - iebrevecyrillic: "04D7", - iecyrillic: "0435", - ieungacirclekorean: "3275", - ieungaparenkorean: "3215", - ieungcirclekorean: "3267", - ieungkorean: "3147", - ieungparenkorean: "3207", - igrave: "00EC", - igujarati: "0A87", - igurmukhi: "0A07", - ihiragana: "3044", - ihookabove: "1EC9", - iibengali: "0988", - iicyrillic: "0438", - iideva: "0908", - iigujarati: "0A88", - iigurmukhi: "0A08", - iimatragurmukhi: "0A40", - iinvertedbreve: "020B", - iishortcyrillic: "0439", - iivowelsignbengali: "09C0", - iivowelsigndeva: "0940", - iivowelsigngujarati: "0AC0", - ij: "0133", - ikatakana: "30A4", - ikatakanahalfwidth: "FF72", - ikorean: "3163", - ilde: "02DC", - iluyhebrew: "05AC", - imacron: "012B", - imacroncyrillic: "04E3", - imageorapproximatelyequal: "2253", - imatragurmukhi: "0A3F", - imonospace: "FF49", - increment: "2206", - infinity: "221E", - iniarmenian: "056B", - integral: "222B", - integralbottom: "2321", - integralbt: "2321", - integralex: "F8F5", - integraltop: "2320", - integraltp: "2320", - intersection: "2229", - intisquare: "3305", - invbullet: "25D8", - invcircle: "25D9", - invsmileface: "263B", - iocyrillic: "0451", - iogonek: "012F", - iota: "03B9", - iotadieresis: "03CA", - iotadieresistonos: "0390", - iotalatin: "0269", - iotatonos: "03AF", - iparen: "24A4", - irigurmukhi: "0A72", - ismallhiragana: "3043", - ismallkatakana: "30A3", - ismallkatakanahalfwidth: "FF68", - issharbengali: "09FA", - istroke: "0268", - isuperior: "F6ED", - iterationhiragana: "309D", - iterationkatakana: "30FD", - itilde: "0129", - itildebelow: "1E2D", - iubopomofo: "3129", - iucyrillic: "044E", - ivowelsignbengali: "09BF", - ivowelsigndeva: "093F", - ivowelsigngujarati: "0ABF", - izhitsacyrillic: "0475", - izhitsadblgravecyrillic: "0477", - j: "006A", - jaarmenian: "0571", - jabengali: "099C", - jadeva: "091C", - jagujarati: "0A9C", - jagurmukhi: "0A1C", - jbopomofo: "3110", - jcaron: "01F0", - jcircle: "24D9", - jcircumflex: "0135", - jcrossedtail: "029D", - jdotlessstroke: "025F", - jecyrillic: "0458", - jeemarabic: "062C", - jeemfinalarabic: "FE9E", - jeeminitialarabic: "FE9F", - jeemmedialarabic: "FEA0", - jeharabic: "0698", - jehfinalarabic: "FB8B", - jhabengali: "099D", - jhadeva: "091D", - jhagujarati: "0A9D", - jhagurmukhi: "0A1D", - jheharmenian: "057B", - jis: "3004", - jmonospace: "FF4A", - jparen: "24A5", - jsuperior: "02B2", - k: "006B", - kabashkircyrillic: "04A1", - kabengali: "0995", - kacute: "1E31", - kacyrillic: "043A", - kadescendercyrillic: "049B", - kadeva: "0915", - kaf: "05DB", - kafarabic: "0643", - kafdagesh: "FB3B", - kafdageshhebrew: "FB3B", - kaffinalarabic: "FEDA", - kafhebrew: "05DB", - kafinitialarabic: "FEDB", - kafmedialarabic: "FEDC", - kafrafehebrew: "FB4D", - kagujarati: "0A95", - kagurmukhi: "0A15", - kahiragana: "304B", - kahookcyrillic: "04C4", - kakatakana: "30AB", - kakatakanahalfwidth: "FF76", - kappa: "03BA", - kappasymbolgreek: "03F0", - kapyeounmieumkorean: "3171", - kapyeounphieuphkorean: "3184", - kapyeounpieupkorean: "3178", - kapyeounssangpieupkorean: "3179", - karoriisquare: "330D", - kashidaautoarabic: "0640", - kashidaautonosidebearingarabic: "0640", - kasmallkatakana: "30F5", - kasquare: "3384", - kasraarabic: "0650", - kasratanarabic: "064D", - kastrokecyrillic: "049F", - katahiraprolongmarkhalfwidth: "FF70", - kaverticalstrokecyrillic: "049D", - kbopomofo: "310E", - kcalsquare: "3389", - kcaron: "01E9", - kcedilla: "0137", - kcircle: "24DA", - kcommaaccent: "0137", - kdotbelow: "1E33", - keharmenian: "0584", - kehiragana: "3051", - kekatakana: "30B1", - kekatakanahalfwidth: "FF79", - kenarmenian: "056F", - kesmallkatakana: "30F6", - kgreenlandic: "0138", - khabengali: "0996", - khacyrillic: "0445", - khadeva: "0916", - khagujarati: "0A96", - khagurmukhi: "0A16", - khaharabic: "062E", - khahfinalarabic: "FEA6", - khahinitialarabic: "FEA7", - khahmedialarabic: "FEA8", - kheicoptic: "03E7", - khhadeva: "0959", - khhagurmukhi: "0A59", - khieukhacirclekorean: "3278", - khieukhaparenkorean: "3218", - khieukhcirclekorean: "326A", - khieukhkorean: "314B", - khieukhparenkorean: "320A", - khokhaithai: "0E02", - khokhonthai: "0E05", - khokhuatthai: "0E03", - khokhwaithai: "0E04", - khomutthai: "0E5B", - khook: "0199", - khorakhangthai: "0E06", - khzsquare: "3391", - kihiragana: "304D", - kikatakana: "30AD", - kikatakanahalfwidth: "FF77", - kiroguramusquare: "3315", - kiromeetorusquare: "3316", - kirosquare: "3314", - kiyeokacirclekorean: "326E", - kiyeokaparenkorean: "320E", - kiyeokcirclekorean: "3260", - kiyeokkorean: "3131", - kiyeokparenkorean: "3200", - kiyeoksioskorean: "3133", - kjecyrillic: "045C", - klinebelow: "1E35", - klsquare: "3398", - kmcubedsquare: "33A6", - kmonospace: "FF4B", - kmsquaredsquare: "33A2", - kohiragana: "3053", - kohmsquare: "33C0", - kokaithai: "0E01", - kokatakana: "30B3", - kokatakanahalfwidth: "FF7A", - kooposquare: "331E", - koppacyrillic: "0481", - koreanstandardsymbol: "327F", - koroniscmb: "0343", - kparen: "24A6", - kpasquare: "33AA", - ksicyrillic: "046F", - ktsquare: "33CF", - kturned: "029E", - kuhiragana: "304F", - kukatakana: "30AF", - kukatakanahalfwidth: "FF78", - kvsquare: "33B8", - kwsquare: "33BE", - l: "006C", - labengali: "09B2", - lacute: "013A", - ladeva: "0932", - lagujarati: "0AB2", - lagurmukhi: "0A32", - lakkhangyaothai: "0E45", - lamaleffinalarabic: "FEFC", - lamalefhamzaabovefinalarabic: "FEF8", - lamalefhamzaaboveisolatedarabic: "FEF7", - lamalefhamzabelowfinalarabic: "FEFA", - lamalefhamzabelowisolatedarabic: "FEF9", - lamalefisolatedarabic: "FEFB", - lamalefmaddaabovefinalarabic: "FEF6", - lamalefmaddaaboveisolatedarabic: "FEF5", - lamarabic: "0644", - lambda: "03BB", - lambdastroke: "019B", - lamed: "05DC", - lameddagesh: "FB3C", - lameddageshhebrew: "FB3C", - lamedhebrew: "05DC", + 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: "FEDE", - lamhahinitialarabic: "FCCA", - laminitialarabic: "FEDF", - lamjeeminitialarabic: "FCC9", - lamkhahinitialarabic: "FCCB", - lamlamhehisolatedarabic: "FDF2", - lammedialarabic: "FEE0", - lammeemhahinitialarabic: "FD88", - lammeeminitialarabic: "FCCC", + 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: "25EF", - lbar: "019A", - lbelt: "026C", - lbopomofo: "310C", - lcaron: "013E", - lcedilla: "013C", - lcircle: "24DB", - lcircumflexbelow: "1E3D", - lcommaaccent: "013C", - ldot: "0140", - ldotaccent: "0140", - ldotbelow: "1E37", - ldotbelowmacron: "1E39", - leftangleabovecmb: "031A", - lefttackbelowcmb: "0318", - less: "003C", - lessequal: "2264", - lessequalorgreater: "22DA", - lessmonospace: "FF1C", - lessorequivalent: "2272", - lessorgreater: "2276", - lessoverequal: "2266", - lesssmall: "FE64", - lezh: "026E", - lfblock: "258C", - lhookretroflex: "026D", - lira: "20A4", - liwnarmenian: "056C", - lj: "01C9", - ljecyrillic: "0459", - ll: "F6C0", - lladeva: "0933", - llagujarati: "0AB3", - llinebelow: "1E3B", - llladeva: "0934", - llvocalicbengali: "09E1", - llvocalicdeva: "0961", - llvocalicvowelsignbengali: "09E3", - llvocalicvowelsigndeva: "0963", - lmiddletilde: "026B", - lmonospace: "FF4C", - lmsquare: "33D0", - lochulathai: "0E2C", - logicaland: "2227", - logicalnot: "00AC", - logicalnotreversed: "2310", - logicalor: "2228", - lolingthai: "0E25", - longs: "017F", - lowlinecenterline: "FE4E", - lowlinecmb: "0332", - lowlinedashed: "FE4D", - lozenge: "25CA", - lparen: "24A7", - lslash: "0142", - lsquare: "2113", - lsuperior: "F6EE", - ltshade: "2591", - luthai: "0E26", - lvocalicbengali: "098C", - lvocalicdeva: "090C", - lvocalicvowelsignbengali: "09E2", - lvocalicvowelsigndeva: "0962", - lxsquare: "33D3", - m: "006D", - mabengali: "09AE", - macron: "00AF", - macronbelowcmb: "0331", - macroncmb: "0304", - macronlowmod: "02CD", - macronmonospace: "FFE3", - macute: "1E3F", - madeva: "092E", - magujarati: "0AAE", - magurmukhi: "0A2E", - mahapakhhebrew: "05A4", - mahapakhlefthebrew: "05A4", - mahiragana: "307E", - maichattawalowleftthai: "F895", - maichattawalowrightthai: "F894", - maichattawathai: "0E4B", - maichattawaupperleftthai: "F893", - maieklowleftthai: "F88C", - maieklowrightthai: "F88B", - maiekthai: "0E48", - maiekupperleftthai: "F88A", - maihanakatleftthai: "F884", - maihanakatthai: "0E31", - maitaikhuleftthai: "F889", - maitaikhuthai: "0E47", - maitholowleftthai: "F88F", - maitholowrightthai: "F88E", - maithothai: "0E49", - maithoupperleftthai: "F88D", - maitrilowleftthai: "F892", - maitrilowrightthai: "F891", - maitrithai: "0E4A", - maitriupperleftthai: "F890", - maiyamokthai: "0E46", - makatakana: "30DE", - makatakanahalfwidth: "FF8F", - male: "2642", - mansyonsquare: "3347", - maqafhebrew: "05BE", - mars: "2642", - masoracirclehebrew: "05AF", - masquare: "3383", - mbopomofo: "3107", - mbsquare: "33D4", - mcircle: "24DC", - mcubedsquare: "33A5", - mdotaccent: "1E41", - mdotbelow: "1E43", - meemarabic: "0645", - meemfinalarabic: "FEE2", - meeminitialarabic: "FEE3", - meemmedialarabic: "FEE4", - meemmeeminitialarabic: "FCD1", - meemmeemisolatedarabic: "FC48", - meetorusquare: "334D", - mehiragana: "3081", - meizierasquare: "337E", - mekatakana: "30E1", - mekatakanahalfwidth: "FF92", - mem: "05DE", - memdagesh: "FB3E", - memdageshhebrew: "FB3E", - memhebrew: "05DE", - menarmenian: "0574", - merkhahebrew: "05A5", - merkhakefulahebrew: "05A6", - merkhakefulalefthebrew: "05A6", - merkhalefthebrew: "05A5", - mhook: "0271", - mhzsquare: "3392", - middledotkatakanahalfwidth: "FF65", - middot: "00B7", - mieumacirclekorean: "3272", - mieumaparenkorean: "3212", - mieumcirclekorean: "3264", - mieumkorean: "3141", - mieumpansioskorean: "3170", - mieumparenkorean: "3204", - mieumpieupkorean: "316E", - mieumsioskorean: "316F", - mihiragana: "307F", - mikatakana: "30DF", - mikatakanahalfwidth: "FF90", - minus: "2212", - minusbelowcmb: "0320", - minuscircle: "2296", - minusmod: "02D7", - minusplus: "2213", - minute: "2032", - miribaarusquare: "334A", - mirisquare: "3349", - mlonglegturned: "0270", - mlsquare: "3396", - mmcubedsquare: "33A3", - mmonospace: "FF4D", - mmsquaredsquare: "339F", - mohiragana: "3082", - mohmsquare: "33C1", - mokatakana: "30E2", - mokatakanahalfwidth: "FF93", - molsquare: "33D6", - momathai: "0E21", - moverssquare: "33A7", - moverssquaredsquare: "33A8", - mparen: "24A8", - mpasquare: "33AB", - mssquare: "33B3", - msuperior: "F6EF", - mturned: "026F", - mu: "00B5", - mu1: "00B5", - muasquare: "3382", - muchgreater: "226B", - muchless: "226A", - mufsquare: "338C", - mugreek: "03BC", - mugsquare: "338D", - muhiragana: "3080", - mukatakana: "30E0", - mukatakanahalfwidth: "FF91", - mulsquare: "3395", - multiply: "00D7", - mumsquare: "339B", - munahhebrew: "05A3", - munahlefthebrew: "05A3", - musicalnote: "266A", - musicalnotedbl: "266B", - musicflatsign: "266D", - musicsharpsign: "266F", - mussquare: "33B2", - muvsquare: "33B6", - muwsquare: "33BC", - mvmegasquare: "33B9", - mvsquare: "33B7", - mwmegasquare: "33BF", - mwsquare: "33BD", - n: "006E", - nabengali: "09A8", - nabla: "2207", - nacute: "0144", - nadeva: "0928", - nagujarati: "0AA8", - nagurmukhi: "0A28", - nahiragana: "306A", - nakatakana: "30CA", - nakatakanahalfwidth: "FF85", - napostrophe: "0149", - nasquare: "3381", - nbopomofo: "310B", - nbspace: "00A0", - ncaron: "0148", - ncedilla: "0146", - ncircle: "24DD", - ncircumflexbelow: "1E4B", - ncommaaccent: "0146", - ndotaccent: "1E45", - ndotbelow: "1E47", - nehiragana: "306D", - nekatakana: "30CD", - nekatakanahalfwidth: "FF88", - newsheqelsign: "20AA", - nfsquare: "338B", - ngabengali: "0999", - ngadeva: "0919", - ngagujarati: "0A99", - ngagurmukhi: "0A19", - ngonguthai: "0E07", - nhiragana: "3093", - nhookleft: "0272", - nhookretroflex: "0273", - nieunacirclekorean: "326F", - nieunaparenkorean: "320F", - nieuncieuckorean: "3135", - nieuncirclekorean: "3261", - nieunhieuhkorean: "3136", - nieunkorean: "3134", - nieunpansioskorean: "3168", - nieunparenkorean: "3201", - nieunsioskorean: "3167", - nieuntikeutkorean: "3166", - nihiragana: "306B", - nikatakana: "30CB", - nikatakanahalfwidth: "FF86", - nikhahitleftthai: "F899", - nikhahitthai: "0E4D", - nine: "0039", - ninearabic: "0669", - ninebengali: "09EF", - ninecircle: "2468", - ninecircleinversesansserif: "2792", - ninedeva: "096F", - ninegujarati: "0AEF", - ninegurmukhi: "0A6F", - ninehackarabic: "0669", - ninehangzhou: "3029", - nineideographicparen: "3228", - nineinferior: "2089", - ninemonospace: "FF19", - nineoldstyle: "F739", - nineparen: "247C", - nineperiod: "2490", - ninepersian: "06F9", - nineroman: "2178", - ninesuperior: "2079", - nineteencircle: "2472", - nineteenparen: "2486", - nineteenperiod: "249A", - ninethai: "0E59", - nj: "01CC", - njecyrillic: "045A", - nkatakana: "30F3", - nkatakanahalfwidth: "FF9D", - nlegrightlong: "019E", - nlinebelow: "1E49", - nmonospace: "FF4E", - nmsquare: "339A", - nnabengali: "09A3", - nnadeva: "0923", - nnagujarati: "0AA3", - nnagurmukhi: "0A23", - nnnadeva: "0929", - nohiragana: "306E", - nokatakana: "30CE", - nokatakanahalfwidth: "FF89", - nonbreakingspace: "00A0", - nonenthai: "0E13", - nonuthai: "0E19", - noonarabic: "0646", - noonfinalarabic: "FEE6", - noonghunnaarabic: "06BA", - noonghunnafinalarabic: "FB9F", + 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: "FEE7", - noonjeeminitialarabic: "FCD2", - noonjeemisolatedarabic: "FC4B", - noonmedialarabic: "FEE8", - noonmeeminitialarabic: "FCD5", - noonmeemisolatedarabic: "FC4E", - noonnoonfinalarabic: "FC8D", - notcontains: "220C", - notelement: "2209", - notelementof: "2209", - notequal: "2260", - notgreater: "226F", - notgreaternorequal: "2271", - notgreaternorless: "2279", - notidentical: "2262", - notless: "226E", - notlessnorequal: "2270", - notparallel: "2226", - notprecedes: "2280", - notsubset: "2284", - notsucceeds: "2281", - notsuperset: "2285", - nowarmenian: "0576", - nparen: "24A9", - nssquare: "33B1", - nsuperior: "207F", - ntilde: "00F1", - nu: "03BD", - nuhiragana: "306C", - nukatakana: "30CC", - nukatakanahalfwidth: "FF87", - nuktabengali: "09BC", - nuktadeva: "093C", - nuktagujarati: "0ABC", - nuktagurmukhi: "0A3C", - numbersign: "0023", - numbersignmonospace: "FF03", - numbersignsmall: "FE5F", - numeralsigngreek: "0374", - numeralsignlowergreek: "0375", - numero: "2116", - nun: "05E0", - nundagesh: "FB40", - nundageshhebrew: "FB40", - nunhebrew: "05E0", - nvsquare: "33B5", - nwsquare: "33BB", - nyabengali: "099E", - nyadeva: "091E", - nyagujarati: "0A9E", - nyagurmukhi: "0A1E", - o: "006F", - oacute: "00F3", - oangthai: "0E2D", - obarred: "0275", - obarredcyrillic: "04E9", - obarreddieresiscyrillic: "04EB", - obengali: "0993", - obopomofo: "311B", - obreve: "014F", - ocandradeva: "0911", - ocandragujarati: "0A91", - ocandravowelsigndeva: "0949", - ocandravowelsigngujarati: "0AC9", - ocaron: "01D2", - ocircle: "24DE", - ocircumflex: "00F4", - ocircumflexacute: "1ED1", - ocircumflexdotbelow: "1ED9", - ocircumflexgrave: "1ED3", - ocircumflexhookabove: "1ED5", - ocircumflextilde: "1ED7", - ocyrillic: "043E", - odblacute: "0151", - odblgrave: "020D", - odeva: "0913", - odieresis: "00F6", - odieresiscyrillic: "04E7", - odotbelow: "1ECD", - oe: "0153", - oekorean: "315A", - ogonek: "02DB", - ogonekcmb: "0328", - ograve: "00F2", - ogujarati: "0A93", - oharmenian: "0585", - ohiragana: "304A", - ohookabove: "1ECF", - ohorn: "01A1", - ohornacute: "1EDB", - ohorndotbelow: "1EE3", - ohorngrave: "1EDD", - ohornhookabove: "1EDF", - ohorntilde: "1EE1", - ohungarumlaut: "0151", - oi: "01A3", - oinvertedbreve: "020F", - okatakana: "30AA", - okatakanahalfwidth: "FF75", - okorean: "3157", - olehebrew: "05AB", - omacron: "014D", - omacronacute: "1E53", - omacrongrave: "1E51", - omdeva: "0950", - omega: "03C9", - omega1: "03D6", - omegacyrillic: "0461", - omegalatinclosed: "0277", - omegaroundcyrillic: "047B", - omegatitlocyrillic: "047D", - omegatonos: "03CE", - omgujarati: "0AD0", - omicron: "03BF", - omicrontonos: "03CC", - omonospace: "FF4F", - one: "0031", - onearabic: "0661", - onebengali: "09E7", - onecircle: "2460", - onecircleinversesansserif: "278A", - onedeva: "0967", - onedotenleader: "2024", - oneeighth: "215B", - onefitted: "F6DC", - onegujarati: "0AE7", - onegurmukhi: "0A67", - onehackarabic: "0661", - onehalf: "00BD", - onehangzhou: "3021", - oneideographicparen: "3220", - oneinferior: "2081", - onemonospace: "FF11", - onenumeratorbengali: "09F4", - oneoldstyle: "F731", - oneparen: "2474", - oneperiod: "2488", - onepersian: "06F1", - onequarter: "00BC", - oneroman: "2170", - onesuperior: "00B9", - onethai: "0E51", - onethird: "2153", - oogonek: "01EB", - oogonekmacron: "01ED", - oogurmukhi: "0A13", - oomatragurmukhi: "0A4B", - oopen: "0254", - oparen: "24AA", - openbullet: "25E6", - option: "2325", - ordfeminine: "00AA", - ordmasculine: "00BA", - orthogonal: "221F", - oshortdeva: "0912", - oshortvowelsigndeva: "094A", - oslash: "00F8", - oslashacute: "01FF", - osmallhiragana: "3049", - osmallkatakana: "30A9", - osmallkatakanahalfwidth: "FF6B", - ostrokeacute: "01FF", - osuperior: "F6F0", - otcyrillic: "047F", - otilde: "00F5", - otildeacute: "1E4D", - otildedieresis: "1E4F", - oubopomofo: "3121", - overline: "203E", - overlinecenterline: "FE4A", - overlinecmb: "0305", - overlinedashed: "FE49", - overlinedblwavy: "FE4C", - overlinewavy: "FE4B", - overscore: "00AF", - ovowelsignbengali: "09CB", - ovowelsigndeva: "094B", - ovowelsigngujarati: "0ACB", - p: "0070", - paampssquare: "3380", - paasentosquare: "332B", - pabengali: "09AA", - pacute: "1E55", - padeva: "092A", - pagedown: "21DF", - pageup: "21DE", - pagujarati: "0AAA", - pagurmukhi: "0A2A", - pahiragana: "3071", - paiyannoithai: "0E2F", - pakatakana: "30D1", - palatalizationcyrilliccmb: "0484", - palochkacyrillic: "04C0", - pansioskorean: "317F", - paragraph: "00B6", - parallel: "2225", - parenleft: "0028", - parenleftaltonearabic: "FD3E", - parenleftbt: "F8ED", - parenleftex: "F8EC", - parenleftinferior: "208D", - parenleftmonospace: "FF08", - parenleftsmall: "FE59", - parenleftsuperior: "207D", - parenlefttp: "F8EB", - parenleftvertical: "FE35", - parenright: "0029", - parenrightaltonearabic: "FD3F", - parenrightbt: "F8F8", - parenrightex: "F8F7", - parenrightinferior: "208E", - parenrightmonospace: "FF09", - parenrightsmall: "FE5A", - parenrightsuperior: "207E", - parenrighttp: "F8F6", - parenrightvertical: "FE36", - partialdiff: "2202", - paseqhebrew: "05C0", - pashtahebrew: "0599", - pasquare: "33A9", - patah: "05B7", - patah11: "05B7", - patah1d: "05B7", - patah2a: "05B7", - patahhebrew: "05B7", - patahnarrowhebrew: "05B7", - patahquarterhebrew: "05B7", - patahwidehebrew: "05B7", - pazerhebrew: "05A1", - pbopomofo: "3106", - pcircle: "24DF", - pdotaccent: "1E57", - pe: "05E4", - pecyrillic: "043F", - pedagesh: "FB44", - pedageshhebrew: "FB44", - peezisquare: "333B", - pefinaldageshhebrew: "FB43", - peharabic: "067E", - peharmenian: "057A", - pehebrew: "05E4", - pehfinalarabic: "FB57", - pehinitialarabic: "FB58", - pehiragana: "307A", - pehmedialarabic: "FB59", - pekatakana: "30DA", - pemiddlehookcyrillic: "04A7", - perafehebrew: "FB4E", - percent: "0025", - percentarabic: "066A", - percentmonospace: "FF05", - percentsmall: "FE6A", - period: "002E", - periodarmenian: "0589", - periodcentered: "00B7", - periodhalfwidth: "FF61", - periodinferior: "F6E7", - periodmonospace: "FF0E", - periodsmall: "FE52", - periodsuperior: "F6E8", - perispomenigreekcmb: "0342", - perpendicular: "22A5", - perthousand: "2030", - peseta: "20A7", - pfsquare: "338A", - phabengali: "09AB", - phadeva: "092B", - phagujarati: "0AAB", - phagurmukhi: "0A2B", - phi: "03C6", - phi1: "03D5", - phieuphacirclekorean: "327A", - phieuphaparenkorean: "321A", - phieuphcirclekorean: "326C", - phieuphkorean: "314D", - phieuphparenkorean: "320C", - philatin: "0278", - phinthuthai: "0E3A", - phisymbolgreek: "03D5", - phook: "01A5", - phophanthai: "0E1E", - phophungthai: "0E1C", - phosamphaothai: "0E20", - pi: "03C0", - pieupacirclekorean: "3273", - pieupaparenkorean: "3213", - pieupcieuckorean: "3176", - pieupcirclekorean: "3265", - pieupkiyeokkorean: "3172", - pieupkorean: "3142", - pieupparenkorean: "3205", - pieupsioskiyeokkorean: "3174", - pieupsioskorean: "3144", - pieupsiostikeutkorean: "3175", - pieupthieuthkorean: "3177", - pieuptikeutkorean: "3173", - pihiragana: "3074", - pikatakana: "30D4", - pisymbolgreek: "03D6", - piwrarmenian: "0583", - plus: "002B", - plusbelowcmb: "031F", - pluscircle: "2295", - plusminus: "00B1", - plusmod: "02D6", - plusmonospace: "FF0B", - plussmall: "FE62", - plussuperior: "207A", - pmonospace: "FF50", - pmsquare: "33D8", - pohiragana: "307D", - pointingindexdownwhite: "261F", - pointingindexleftwhite: "261C", - pointingindexrightwhite: "261E", - pointingindexupwhite: "261D", - pokatakana: "30DD", - poplathai: "0E1B", - postalmark: "3012", - postalmarkface: "3020", - pparen: "24AB", - precedes: "227A", - prescription: "211E", - primemod: "02B9", - primereversed: "2035", - product: "220F", - projective: "2305", - prolongedkana: "30FC", - propellor: "2318", - propersubset: "2282", - propersuperset: "2283", - proportion: "2237", - proportional: "221D", - psi: "03C8", - psicyrillic: "0471", - psilipneumatacyrilliccmb: "0486", - pssquare: "33B0", - puhiragana: "3077", - pukatakana: "30D7", - pvsquare: "33B4", - pwsquare: "33BA", - q: "0071", - qadeva: "0958", - qadmahebrew: "05A8", - qafarabic: "0642", - qaffinalarabic: "FED6", - qafinitialarabic: "FED7", - qafmedialarabic: "FED8", - qamats: "05B8", - qamats10: "05B8", - qamats1a: "05B8", - qamats1c: "05B8", - qamats27: "05B8", - qamats29: "05B8", - qamats33: "05B8", - qamatsde: "05B8", - qamatshebrew: "05B8", - qamatsnarrowhebrew: "05B8", - qamatsqatanhebrew: "05B8", - qamatsqatannarrowhebrew: "05B8", - qamatsqatanquarterhebrew: "05B8", - qamatsqatanwidehebrew: "05B8", - qamatsquarterhebrew: "05B8", - qamatswidehebrew: "05B8", - qarneyparahebrew: "059F", - qbopomofo: "3111", - qcircle: "24E0", - qhook: "02A0", - qmonospace: "FF51", - qof: "05E7", - qofdagesh: "FB47", - qofdageshhebrew: "FB47", + 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: "05E7", + qofhebrew: 0x05E7, qofhiriq: "05E7 05B4", qofhiriqhebrew: "05E7 05B4", qofholam: "05E7 05B9", @@ -3172,89 +3172,89 @@ var GlyphsUnicode = { qofshevahebrew: "05E7 05B0", qoftsere: "05E7 05B5", qoftserehebrew: "05E7 05B5", - qparen: "24AC", - quarternote: "2669", - qubuts: "05BB", - qubuts18: "05BB", - qubuts25: "05BB", - qubuts31: "05BB", - qubutshebrew: "05BB", - qubutsnarrowhebrew: "05BB", - qubutsquarterhebrew: "05BB", - qubutswidehebrew: "05BB", - question: "003F", - questionarabic: "061F", - questionarmenian: "055E", - questiondown: "00BF", - questiondownsmall: "F7BF", - questiongreek: "037E", - questionmonospace: "FF1F", - questionsmall: "F73F", - quotedbl: "0022", - quotedblbase: "201E", - quotedblleft: "201C", - quotedblmonospace: "FF02", - quotedblprime: "301E", - quotedblprimereversed: "301D", - quotedblright: "201D", - quoteleft: "2018", - quoteleftreversed: "201B", - quotereversed: "201B", - quoteright: "2019", - quoterightn: "0149", - quotesinglbase: "201A", - quotesingle: "0027", - quotesinglemonospace: "FF07", - r: "0072", - raarmenian: "057C", - rabengali: "09B0", - racute: "0155", - radeva: "0930", - radical: "221A", - radicalex: "F8E5", - radoverssquare: "33AE", - radoverssquaredsquare: "33AF", - radsquare: "33AD", - rafe: "05BF", - rafehebrew: "05BF", - ragujarati: "0AB0", - ragurmukhi: "0A30", - rahiragana: "3089", - rakatakana: "30E9", - rakatakanahalfwidth: "FF97", - ralowerdiagonalbengali: "09F1", - ramiddlediagonalbengali: "09F0", - ramshorn: "0264", - ratio: "2236", - rbopomofo: "3116", - rcaron: "0159", - rcedilla: "0157", - rcircle: "24E1", - rcommaaccent: "0157", - rdblgrave: "0211", - rdotaccent: "1E59", - rdotbelow: "1E5B", - rdotbelowmacron: "1E5D", - referencemark: "203B", - reflexsubset: "2286", - reflexsuperset: "2287", - registered: "00AE", - registersans: "F8E8", - registerserif: "F6DA", - reharabic: "0631", - reharmenian: "0580", - rehfinalarabic: "FEAE", - rehiragana: "308C", + 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: "30EC", - rekatakanahalfwidth: "FF9A", - resh: "05E8", - reshdageshhebrew: "FB48", + rekatakana: 0x30EC, + rekatakanahalfwidth: 0xFF9A, + resh: 0x05E8, + reshdageshhebrew: 0xFB48, reshhatafpatah: "05E8 05B2", reshhatafpatahhebrew: "05E8 05B2", reshhatafsegol: "05E8 05B1", reshhatafsegolhebrew: "05E8 05B1", - reshhebrew: "05E8", + reshhebrew: 0x05E8, reshhiriq: "05E8 05B4", reshhiriqhebrew: "05E8 05B4", reshholam: "05E8 05B9", @@ -3271,1019 +3271,1019 @@ var GlyphsUnicode = { reshshevahebrew: "05E8 05B0", reshtsere: "05E8 05B5", reshtserehebrew: "05E8 05B5", - reversedtilde: "223D", - reviahebrew: "0597", - reviamugrashhebrew: "0597", - revlogicalnot: "2310", - rfishhook: "027E", - rfishhookreversed: "027F", - rhabengali: "09DD", - rhadeva: "095D", - rho: "03C1", - rhook: "027D", - rhookturned: "027B", - rhookturnedsuperior: "02B5", - rhosymbolgreek: "03F1", - rhotichookmod: "02DE", - rieulacirclekorean: "3271", - rieulaparenkorean: "3211", - rieulcirclekorean: "3263", - rieulhieuhkorean: "3140", - rieulkiyeokkorean: "313A", - rieulkiyeoksioskorean: "3169", - rieulkorean: "3139", - rieulmieumkorean: "313B", - rieulpansioskorean: "316C", - rieulparenkorean: "3203", - rieulphieuphkorean: "313F", - rieulpieupkorean: "313C", - rieulpieupsioskorean: "316B", - rieulsioskorean: "313D", - rieulthieuthkorean: "313E", - rieultikeutkorean: "316A", - rieulyeorinhieuhkorean: "316D", - rightangle: "221F", - righttackbelowcmb: "0319", - righttriangle: "22BF", - rihiragana: "308A", - rikatakana: "30EA", - rikatakanahalfwidth: "FF98", - ring: "02DA", - ringbelowcmb: "0325", - ringcmb: "030A", - ringhalfleft: "02BF", - ringhalfleftarmenian: "0559", - ringhalfleftbelowcmb: "031C", - ringhalfleftcentered: "02D3", - ringhalfright: "02BE", - ringhalfrightbelowcmb: "0339", - ringhalfrightcentered: "02D2", - rinvertedbreve: "0213", - rittorusquare: "3351", - rlinebelow: "1E5F", - rlongleg: "027C", - rlonglegturned: "027A", - rmonospace: "FF52", - rohiragana: "308D", - rokatakana: "30ED", - rokatakanahalfwidth: "FF9B", - roruathai: "0E23", - rparen: "24AD", - rrabengali: "09DC", - rradeva: "0931", - rragurmukhi: "0A5C", - rreharabic: "0691", - rrehfinalarabic: "FB8D", - rrvocalicbengali: "09E0", - rrvocalicdeva: "0960", - rrvocalicgujarati: "0AE0", - rrvocalicvowelsignbengali: "09C4", - rrvocalicvowelsigndeva: "0944", - rrvocalicvowelsigngujarati: "0AC4", - rsuperior: "F6F1", - rtblock: "2590", - rturned: "0279", - rturnedsuperior: "02B4", - ruhiragana: "308B", - rukatakana: "30EB", - rukatakanahalfwidth: "FF99", - rupeemarkbengali: "09F2", - rupeesignbengali: "09F3", - rupiah: "F6DD", - ruthai: "0E24", - rvocalicbengali: "098B", - rvocalicdeva: "090B", - rvocalicgujarati: "0A8B", - rvocalicvowelsignbengali: "09C3", - rvocalicvowelsigndeva: "0943", - rvocalicvowelsigngujarati: "0AC3", - s: "0073", - sabengali: "09B8", - sacute: "015B", - sacutedotaccent: "1E65", - sadarabic: "0635", - sadeva: "0938", - sadfinalarabic: "FEBA", - sadinitialarabic: "FEBB", - sadmedialarabic: "FEBC", - sagujarati: "0AB8", - sagurmukhi: "0A38", - sahiragana: "3055", - sakatakana: "30B5", - sakatakanahalfwidth: "FF7B", - sallallahoualayhewasallamarabic: "FDFA", - samekh: "05E1", - samekhdagesh: "FB41", - samekhdageshhebrew: "FB41", - samekhhebrew: "05E1", - saraaathai: "0E32", - saraaethai: "0E41", - saraaimaimalaithai: "0E44", - saraaimaimuanthai: "0E43", - saraamthai: "0E33", - saraathai: "0E30", - saraethai: "0E40", - saraiileftthai: "F886", - saraiithai: "0E35", - saraileftthai: "F885", - saraithai: "0E34", - saraothai: "0E42", - saraueeleftthai: "F888", - saraueethai: "0E37", - saraueleftthai: "F887", - sarauethai: "0E36", - sarauthai: "0E38", - sarauuthai: "0E39", - sbopomofo: "3119", - scaron: "0161", - scarondotaccent: "1E67", - scedilla: "015F", - schwa: "0259", - schwacyrillic: "04D9", - schwadieresiscyrillic: "04DB", - schwahook: "025A", - scircle: "24E2", - scircumflex: "015D", - scommaaccent: "0219", - sdotaccent: "1E61", - sdotbelow: "1E63", - sdotbelowdotaccent: "1E69", - seagullbelowcmb: "033C", - second: "2033", - secondtonechinese: "02CA", - section: "00A7", - seenarabic: "0633", - seenfinalarabic: "FEB2", - seeninitialarabic: "FEB3", - seenmedialarabic: "FEB4", - segol: "05B6", - segol13: "05B6", - segol1f: "05B6", - segol2c: "05B6", - segolhebrew: "05B6", - segolnarrowhebrew: "05B6", - segolquarterhebrew: "05B6", - segoltahebrew: "0592", - segolwidehebrew: "05B6", - seharmenian: "057D", - sehiragana: "305B", - sekatakana: "30BB", - sekatakanahalfwidth: "FF7E", - semicolon: "003B", - semicolonarabic: "061B", - semicolonmonospace: "FF1B", - semicolonsmall: "FE54", - semivoicedmarkkana: "309C", - semivoicedmarkkanahalfwidth: "FF9F", - sentisquare: "3322", - sentosquare: "3323", - seven: "0037", - sevenarabic: "0667", - sevenbengali: "09ED", - sevencircle: "2466", - sevencircleinversesansserif: "2790", - sevendeva: "096D", - seveneighths: "215E", - sevengujarati: "0AED", - sevengurmukhi: "0A6D", - sevenhackarabic: "0667", - sevenhangzhou: "3027", - sevenideographicparen: "3226", - seveninferior: "2087", - sevenmonospace: "FF17", - sevenoldstyle: "F737", - sevenparen: "247A", - sevenperiod: "248E", - sevenpersian: "06F7", - sevenroman: "2176", - sevensuperior: "2077", - seventeencircle: "2470", - seventeenparen: "2484", - seventeenperiod: "2498", - seventhai: "0E57", - sfthyphen: "00AD", - shaarmenian: "0577", - shabengali: "09B6", - shacyrillic: "0448", - shaddaarabic: "0651", - shaddadammaarabic: "FC61", - shaddadammatanarabic: "FC5E", - shaddafathaarabic: "FC60", + 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: "FC62", - shaddakasratanarabic: "FC5F", - shade: "2592", - shadedark: "2593", - shadelight: "2591", - shademedium: "2592", - shadeva: "0936", - shagujarati: "0AB6", - shagurmukhi: "0A36", - shalshelethebrew: "0593", - shbopomofo: "3115", - shchacyrillic: "0449", - sheenarabic: "0634", - sheenfinalarabic: "FEB6", - sheeninitialarabic: "FEB7", - sheenmedialarabic: "FEB8", - sheicoptic: "03E3", - sheqel: "20AA", - sheqelhebrew: "20AA", - sheva: "05B0", - sheva115: "05B0", - sheva15: "05B0", - sheva22: "05B0", - sheva2e: "05B0", - shevahebrew: "05B0", - shevanarrowhebrew: "05B0", - shevaquarterhebrew: "05B0", - shevawidehebrew: "05B0", - shhacyrillic: "04BB", - shimacoptic: "03ED", - shin: "05E9", - shindagesh: "FB49", - shindageshhebrew: "FB49", - shindageshshindot: "FB2C", - shindageshshindothebrew: "FB2C", - shindageshsindot: "FB2D", - shindageshsindothebrew: "FB2D", - shindothebrew: "05C1", - shinhebrew: "05E9", - shinshindot: "FB2A", - shinshindothebrew: "FB2A", - shinsindot: "FB2B", - shinsindothebrew: "FB2B", - shook: "0282", - sigma: "03C3", - sigma1: "03C2", - sigmafinal: "03C2", - sigmalunatesymbolgreek: "03F2", - sihiragana: "3057", - sikatakana: "30B7", - sikatakanahalfwidth: "FF7C", - siluqhebrew: "05BD", - siluqlefthebrew: "05BD", - similar: "223C", - sindothebrew: "05C2", - siosacirclekorean: "3274", - siosaparenkorean: "3214", - sioscieuckorean: "317E", - sioscirclekorean: "3266", - sioskiyeokkorean: "317A", - sioskorean: "3145", - siosnieunkorean: "317B", - siosparenkorean: "3206", - siospieupkorean: "317D", - siostikeutkorean: "317C", - six: "0036", - sixarabic: "0666", - sixbengali: "09EC", - sixcircle: "2465", - sixcircleinversesansserif: "278F", - sixdeva: "096C", - sixgujarati: "0AEC", - sixgurmukhi: "0A6C", - sixhackarabic: "0666", - sixhangzhou: "3026", - sixideographicparen: "3225", - sixinferior: "2086", - sixmonospace: "FF16", - sixoldstyle: "F736", - sixparen: "2479", - sixperiod: "248D", - sixpersian: "06F6", - sixroman: "2175", - sixsuperior: "2076", - sixteencircle: "246F", - sixteencurrencydenominatorbengali: "09F9", - sixteenparen: "2483", - sixteenperiod: "2497", - sixthai: "0E56", - slash: "002F", - slashmonospace: "FF0F", - slong: "017F", - slongdotaccent: "1E9B", - smileface: "263A", - smonospace: "FF53", - sofpasuqhebrew: "05C3", - softhyphen: "00AD", - softsigncyrillic: "044C", - sohiragana: "305D", - sokatakana: "30BD", - sokatakanahalfwidth: "FF7F", - soliduslongoverlaycmb: "0338", - solidusshortoverlaycmb: "0337", - sorusithai: "0E29", - sosalathai: "0E28", - sosothai: "0E0B", - sosuathai: "0E2A", - space: "0020", - spacehackarabic: "0020", - spade: "2660", - spadesuitblack: "2660", - spadesuitwhite: "2664", - sparen: "24AE", - squarebelowcmb: "033B", - squarecc: "33C4", - squarecm: "339D", - squarediagonalcrosshatchfill: "25A9", - squarehorizontalfill: "25A4", - squarekg: "338F", - squarekm: "339E", - squarekmcapital: "33CE", - squareln: "33D1", - squarelog: "33D2", - squaremg: "338E", - squaremil: "33D5", - squaremm: "339C", - squaremsquared: "33A1", - squareorthogonalcrosshatchfill: "25A6", - squareupperlefttolowerrightfill: "25A7", - squareupperrighttolowerleftfill: "25A8", - squareverticalfill: "25A5", - squarewhitewithsmallblack: "25A3", - srsquare: "33DB", - ssabengali: "09B7", - ssadeva: "0937", - ssagujarati: "0AB7", - ssangcieuckorean: "3149", - ssanghieuhkorean: "3185", - ssangieungkorean: "3180", - ssangkiyeokkorean: "3132", - ssangnieunkorean: "3165", - ssangpieupkorean: "3143", - ssangsioskorean: "3146", - ssangtikeutkorean: "3138", - ssuperior: "F6F2", - sterling: "00A3", - sterlingmonospace: "FFE1", - strokelongoverlaycmb: "0336", - strokeshortoverlaycmb: "0335", - subset: "2282", - subsetnotequal: "228A", - subsetorequal: "2286", - succeeds: "227B", - suchthat: "220B", - suhiragana: "3059", - sukatakana: "30B9", - sukatakanahalfwidth: "FF7D", - sukunarabic: "0652", - summation: "2211", - sun: "263C", - superset: "2283", - supersetnotequal: "228B", - supersetorequal: "2287", - svsquare: "33DC", - syouwaerasquare: "337C", - t: "0074", - tabengali: "09A4", - tackdown: "22A4", - tackleft: "22A3", - tadeva: "0924", - tagujarati: "0AA4", - tagurmukhi: "0A24", - taharabic: "0637", - tahfinalarabic: "FEC2", - tahinitialarabic: "FEC3", - tahiragana: "305F", - tahmedialarabic: "FEC4", - taisyouerasquare: "337D", - takatakana: "30BF", - takatakanahalfwidth: "FF80", - tatweelarabic: "0640", - tau: "03C4", - tav: "05EA", - tavdages: "FB4A", - tavdagesh: "FB4A", - tavdageshhebrew: "FB4A", - tavhebrew: "05EA", - tbar: "0167", - tbopomofo: "310A", - tcaron: "0165", - tccurl: "02A8", - tcedilla: "0163", - tcheharabic: "0686", - tchehfinalarabic: "FB7B", - tchehinitialarabic: "FB7C", - tchehmedialarabic: "FB7D", + 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: "24E3", - tcircumflexbelow: "1E71", - tcommaaccent: "0163", - tdieresis: "1E97", - tdotaccent: "1E6B", - tdotbelow: "1E6D", - tecyrillic: "0442", - tedescendercyrillic: "04AD", - teharabic: "062A", - tehfinalarabic: "FE96", - tehhahinitialarabic: "FCA2", - tehhahisolatedarabic: "FC0C", - tehinitialarabic: "FE97", - tehiragana: "3066", - tehjeeminitialarabic: "FCA1", - tehjeemisolatedarabic: "FC0B", - tehmarbutaarabic: "0629", - tehmarbutafinalarabic: "FE94", - tehmedialarabic: "FE98", - tehmeeminitialarabic: "FCA4", - tehmeemisolatedarabic: "FC0E", - tehnoonfinalarabic: "FC73", - tekatakana: "30C6", - tekatakanahalfwidth: "FF83", - telephone: "2121", - telephoneblack: "260E", - telishagedolahebrew: "05A0", - telishaqetanahebrew: "05A9", - tencircle: "2469", - tenideographicparen: "3229", - tenparen: "247D", - tenperiod: "2491", - tenroman: "2179", - tesh: "02A7", - tet: "05D8", - tetdagesh: "FB38", - tetdageshhebrew: "FB38", - tethebrew: "05D8", - tetsecyrillic: "04B5", - tevirhebrew: "059B", - tevirlefthebrew: "059B", - thabengali: "09A5", - thadeva: "0925", - thagujarati: "0AA5", - thagurmukhi: "0A25", - thalarabic: "0630", - thalfinalarabic: "FEAC", - thanthakhatlowleftthai: "F898", - thanthakhatlowrightthai: "F897", - thanthakhatthai: "0E4C", - thanthakhatupperleftthai: "F896", - theharabic: "062B", - thehfinalarabic: "FE9A", - thehinitialarabic: "FE9B", - thehmedialarabic: "FE9C", - thereexists: "2203", - therefore: "2234", - theta: "03B8", - theta1: "03D1", - thetasymbolgreek: "03D1", - thieuthacirclekorean: "3279", - thieuthaparenkorean: "3219", - thieuthcirclekorean: "326B", - thieuthkorean: "314C", - thieuthparenkorean: "320B", - thirteencircle: "246C", - thirteenparen: "2480", - thirteenperiod: "2494", - thonangmonthothai: "0E11", - thook: "01AD", - thophuthaothai: "0E12", - thorn: "00FE", - thothahanthai: "0E17", - thothanthai: "0E10", - thothongthai: "0E18", - thothungthai: "0E16", - thousandcyrillic: "0482", - thousandsseparatorarabic: "066C", - thousandsseparatorpersian: "066C", - three: "0033", - threearabic: "0663", - threebengali: "09E9", - threecircle: "2462", - threecircleinversesansserif: "278C", - threedeva: "0969", - threeeighths: "215C", - threegujarati: "0AE9", - threegurmukhi: "0A69", - threehackarabic: "0663", - threehangzhou: "3023", - threeideographicparen: "3222", - threeinferior: "2083", - threemonospace: "FF13", - threenumeratorbengali: "09F6", - threeoldstyle: "F733", - threeparen: "2476", - threeperiod: "248A", - threepersian: "06F3", - threequarters: "00BE", - threequartersemdash: "F6DE", - threeroman: "2172", - threesuperior: "00B3", - threethai: "0E53", - thzsquare: "3394", - tihiragana: "3061", - tikatakana: "30C1", - tikatakanahalfwidth: "FF81", - tikeutacirclekorean: "3270", - tikeutaparenkorean: "3210", - tikeutcirclekorean: "3262", - tikeutkorean: "3137", - tikeutparenkorean: "3202", - tilde: "02DC", - tildebelowcmb: "0330", - tildecmb: "0303", - tildecomb: "0303", - tildedoublecmb: "0360", - tildeoperator: "223C", - tildeoverlaycmb: "0334", - tildeverticalcmb: "033E", - timescircle: "2297", - tipehahebrew: "0596", - tipehalefthebrew: "0596", - tippigurmukhi: "0A70", - titlocyrilliccmb: "0483", - tiwnarmenian: "057F", - tlinebelow: "1E6F", - tmonospace: "FF54", - toarmenian: "0569", - tohiragana: "3068", - tokatakana: "30C8", - tokatakanahalfwidth: "FF84", - tonebarextrahighmod: "02E5", - tonebarextralowmod: "02E9", - tonebarhighmod: "02E6", - tonebarlowmod: "02E8", - tonebarmidmod: "02E7", - tonefive: "01BD", - tonesix: "0185", - tonetwo: "01A8", - tonos: "0384", - tonsquare: "3327", - topatakthai: "0E0F", - tortoiseshellbracketleft: "3014", - tortoiseshellbracketleftsmall: "FE5D", - tortoiseshellbracketleftvertical: "FE39", - tortoiseshellbracketright: "3015", - tortoiseshellbracketrightsmall: "FE5E", - tortoiseshellbracketrightvertical: "FE3A", - totaothai: "0E15", - tpalatalhook: "01AB", - tparen: "24AF", - trademark: "2122", - trademarksans: "F8EA", - trademarkserif: "F6DB", - tretroflexhook: "0288", - triagdn: "25BC", - triaglf: "25C4", - triagrt: "25BA", - triagup: "25B2", - ts: "02A6", - tsadi: "05E6", - tsadidagesh: "FB46", - tsadidageshhebrew: "FB46", - tsadihebrew: "05E6", - tsecyrillic: "0446", - tsere: "05B5", - tsere12: "05B5", - tsere1e: "05B5", - tsere2b: "05B5", - tserehebrew: "05B5", - tserenarrowhebrew: "05B5", - tserequarterhebrew: "05B5", - tserewidehebrew: "05B5", - tshecyrillic: "045B", - tsuperior: "F6F3", - ttabengali: "099F", - ttadeva: "091F", - ttagujarati: "0A9F", - ttagurmukhi: "0A1F", - tteharabic: "0679", - ttehfinalarabic: "FB67", - ttehinitialarabic: "FB68", - ttehmedialarabic: "FB69", - tthabengali: "09A0", - tthadeva: "0920", - tthagujarati: "0AA0", - tthagurmukhi: "0A20", - tturned: "0287", - tuhiragana: "3064", - tukatakana: "30C4", - tukatakanahalfwidth: "FF82", - tusmallhiragana: "3063", - tusmallkatakana: "30C3", - tusmallkatakanahalfwidth: "FF6F", - twelvecircle: "246B", - twelveparen: "247F", - twelveperiod: "2493", - twelveroman: "217B", - twentycircle: "2473", - twentyhangzhou: "5344", - twentyparen: "2487", - twentyperiod: "249B", - two: "0032", - twoarabic: "0662", - twobengali: "09E8", - twocircle: "2461", - twocircleinversesansserif: "278B", - twodeva: "0968", - twodotenleader: "2025", - twodotleader: "2025", - twodotleadervertical: "FE30", - twogujarati: "0AE8", - twogurmukhi: "0A68", - twohackarabic: "0662", - twohangzhou: "3022", - twoideographicparen: "3221", - twoinferior: "2082", - twomonospace: "FF12", - twonumeratorbengali: "09F5", - twooldstyle: "F732", - twoparen: "2475", - twoperiod: "2489", - twopersian: "06F2", - tworoman: "2171", - twostroke: "01BB", - twosuperior: "00B2", - twothai: "0E52", - twothirds: "2154", - u: "0075", - uacute: "00FA", - ubar: "0289", - ubengali: "0989", - ubopomofo: "3128", - ubreve: "016D", - ucaron: "01D4", - ucircle: "24E4", - ucircumflex: "00FB", - ucircumflexbelow: "1E77", - ucyrillic: "0443", - udattadeva: "0951", - udblacute: "0171", - udblgrave: "0215", - udeva: "0909", - udieresis: "00FC", - udieresisacute: "01D8", - udieresisbelow: "1E73", - udieresiscaron: "01DA", - udieresiscyrillic: "04F1", - udieresisgrave: "01DC", - udieresismacron: "01D6", - udotbelow: "1EE5", - ugrave: "00F9", - ugujarati: "0A89", - ugurmukhi: "0A09", - uhiragana: "3046", - uhookabove: "1EE7", - uhorn: "01B0", - uhornacute: "1EE9", - uhorndotbelow: "1EF1", - uhorngrave: "1EEB", - uhornhookabove: "1EED", - uhorntilde: "1EEF", - uhungarumlaut: "0171", - uhungarumlautcyrillic: "04F3", - uinvertedbreve: "0217", - ukatakana: "30A6", - ukatakanahalfwidth: "FF73", - ukcyrillic: "0479", - ukorean: "315C", - umacron: "016B", - umacroncyrillic: "04EF", - umacrondieresis: "1E7B", - umatragurmukhi: "0A41", - umonospace: "FF55", - underscore: "005F", - underscoredbl: "2017", - underscoremonospace: "FF3F", - underscorevertical: "FE33", - underscorewavy: "FE4F", - union: "222A", - universal: "2200", - uogonek: "0173", - uparen: "24B0", - upblock: "2580", - upperdothebrew: "05C4", - upsilon: "03C5", - upsilondieresis: "03CB", - upsilondieresistonos: "03B0", - upsilonlatin: "028A", - upsilontonos: "03CD", - uptackbelowcmb: "031D", - uptackmod: "02D4", - uragurmukhi: "0A73", - uring: "016F", - ushortcyrillic: "045E", - usmallhiragana: "3045", - usmallkatakana: "30A5", - usmallkatakanahalfwidth: "FF69", - ustraightcyrillic: "04AF", - ustraightstrokecyrillic: "04B1", - utilde: "0169", - utildeacute: "1E79", - utildebelow: "1E75", - uubengali: "098A", - uudeva: "090A", - uugujarati: "0A8A", - uugurmukhi: "0A0A", - uumatragurmukhi: "0A42", - uuvowelsignbengali: "09C2", - uuvowelsigndeva: "0942", - uuvowelsigngujarati: "0AC2", - uvowelsignbengali: "09C1", - uvowelsigndeva: "0941", - uvowelsigngujarati: "0AC1", - v: "0076", - vadeva: "0935", - vagujarati: "0AB5", - vagurmukhi: "0A35", - vakatakana: "30F7", - vav: "05D5", - vavdagesh: "FB35", - vavdagesh65: "FB35", - vavdageshhebrew: "FB35", - vavhebrew: "05D5", - vavholam: "FB4B", - vavholamhebrew: "FB4B", - vavvavhebrew: "05F0", - vavyodhebrew: "05F1", - vcircle: "24E5", - vdotbelow: "1E7F", - vecyrillic: "0432", - veharabic: "06A4", - vehfinalarabic: "FB6B", - vehinitialarabic: "FB6C", - vehmedialarabic: "FB6D", - vekatakana: "30F9", - venus: "2640", - verticalbar: "007C", - verticallineabovecmb: "030D", - verticallinebelowcmb: "0329", - verticallinelowmod: "02CC", - verticallinemod: "02C8", - vewarmenian: "057E", - vhook: "028B", - vikatakana: "30F8", - viramabengali: "09CD", - viramadeva: "094D", - viramagujarati: "0ACD", - visargabengali: "0983", - visargadeva: "0903", - visargagujarati: "0A83", - vmonospace: "FF56", - voarmenian: "0578", - voicediterationhiragana: "309E", - voicediterationkatakana: "30FE", - voicedmarkkana: "309B", - voicedmarkkanahalfwidth: "FF9E", - vokatakana: "30FA", - vparen: "24B1", - vtilde: "1E7D", - vturned: "028C", - vuhiragana: "3094", - vukatakana: "30F4", - w: "0077", - wacute: "1E83", - waekorean: "3159", - wahiragana: "308F", - wakatakana: "30EF", - wakatakanahalfwidth: "FF9C", - wakorean: "3158", - wasmallhiragana: "308E", - wasmallkatakana: "30EE", - wattosquare: "3357", - wavedash: "301C", - wavyunderscorevertical: "FE34", - wawarabic: "0648", - wawfinalarabic: "FEEE", - wawhamzaabovearabic: "0624", - wawhamzaabovefinalarabic: "FE86", - wbsquare: "33DD", - wcircle: "24E6", - wcircumflex: "0175", - wdieresis: "1E85", - wdotaccent: "1E87", - wdotbelow: "1E89", - wehiragana: "3091", - weierstrass: "2118", - wekatakana: "30F1", - wekorean: "315E", - weokorean: "315D", - wgrave: "1E81", - whitebullet: "25E6", - whitecircle: "25CB", - whitecircleinverse: "25D9", - whitecornerbracketleft: "300E", - whitecornerbracketleftvertical: "FE43", - whitecornerbracketright: "300F", - whitecornerbracketrightvertical: "FE44", - whitediamond: "25C7", - whitediamondcontainingblacksmalldiamond: "25C8", - whitedownpointingsmalltriangle: "25BF", - whitedownpointingtriangle: "25BD", - whiteleftpointingsmalltriangle: "25C3", - whiteleftpointingtriangle: "25C1", - whitelenticularbracketleft: "3016", - whitelenticularbracketright: "3017", - whiterightpointingsmalltriangle: "25B9", - whiterightpointingtriangle: "25B7", - whitesmallsquare: "25AB", - whitesmilingface: "263A", - whitesquare: "25A1", - whitestar: "2606", - whitetelephone: "260F", - whitetortoiseshellbracketleft: "3018", - whitetortoiseshellbracketright: "3019", - whiteuppointingsmalltriangle: "25B5", - whiteuppointingtriangle: "25B3", - wihiragana: "3090", - wikatakana: "30F0", - wikorean: "315F", - wmonospace: "FF57", - wohiragana: "3092", - wokatakana: "30F2", - wokatakanahalfwidth: "FF66", - won: "20A9", - wonmonospace: "FFE6", - wowaenthai: "0E27", - wparen: "24B2", - wring: "1E98", - wsuperior: "02B7", - wturned: "028D", - wynn: "01BF", - x: "0078", - xabovecmb: "033D", - xbopomofo: "3112", - xcircle: "24E7", - xdieresis: "1E8D", - xdotaccent: "1E8B", - xeharmenian: "056D", - xi: "03BE", - xmonospace: "FF58", - xparen: "24B3", - xsuperior: "02E3", - y: "0079", - yaadosquare: "334E", - yabengali: "09AF", - yacute: "00FD", - yadeva: "092F", - yaekorean: "3152", - yagujarati: "0AAF", - yagurmukhi: "0A2F", - yahiragana: "3084", - yakatakana: "30E4", - yakatakanahalfwidth: "FF94", - yakorean: "3151", - yamakkanthai: "0E4E", - yasmallhiragana: "3083", - yasmallkatakana: "30E3", - yasmallkatakanahalfwidth: "FF6C", - yatcyrillic: "0463", - ycircle: "24E8", - ycircumflex: "0177", - ydieresis: "00FF", - ydotaccent: "1E8F", - ydotbelow: "1EF5", - yeharabic: "064A", - yehbarreearabic: "06D2", - yehbarreefinalarabic: "FBAF", - yehfinalarabic: "FEF2", - yehhamzaabovearabic: "0626", - yehhamzaabovefinalarabic: "FE8A", - yehhamzaaboveinitialarabic: "FE8B", - yehhamzaabovemedialarabic: "FE8C", - yehinitialarabic: "FEF3", - yehmedialarabic: "FEF4", - yehmeeminitialarabic: "FCDD", - yehmeemisolatedarabic: "FC58", - yehnoonfinalarabic: "FC94", - yehthreedotsbelowarabic: "06D1", - yekorean: "3156", - yen: "00A5", - yenmonospace: "FFE5", - yeokorean: "3155", - yeorinhieuhkorean: "3186", - yerahbenyomohebrew: "05AA", - yerahbenyomolefthebrew: "05AA", - yericyrillic: "044B", - yerudieresiscyrillic: "04F9", - yesieungkorean: "3181", - yesieungpansioskorean: "3183", - yesieungsioskorean: "3182", - yetivhebrew: "059A", - ygrave: "1EF3", - yhook: "01B4", - yhookabove: "1EF7", - yiarmenian: "0575", - yicyrillic: "0457", - yikorean: "3162", - yinyang: "262F", - yiwnarmenian: "0582", - ymonospace: "FF59", - yod: "05D9", - yoddagesh: "FB39", - yoddageshhebrew: "FB39", - yodhebrew: "05D9", - yodyodhebrew: "05F2", - yodyodpatahhebrew: "FB1F", - yohiragana: "3088", - yoikorean: "3189", - yokatakana: "30E8", - yokatakanahalfwidth: "FF96", - yokorean: "315B", - yosmallhiragana: "3087", - yosmallkatakana: "30E7", - yosmallkatakanahalfwidth: "FF6E", - yotgreek: "03F3", - yoyaekorean: "3188", - yoyakorean: "3187", - yoyakthai: "0E22", - yoyingthai: "0E0D", - yparen: "24B4", - ypogegrammeni: "037A", - ypogegrammenigreekcmb: "0345", - yr: "01A6", - yring: "1E99", - ysuperior: "02B8", - ytilde: "1EF9", - yturned: "028E", - yuhiragana: "3086", - yuikorean: "318C", - yukatakana: "30E6", - yukatakanahalfwidth: "FF95", - yukorean: "3160", - yusbigcyrillic: "046B", - yusbigiotifiedcyrillic: "046D", - yuslittlecyrillic: "0467", - yuslittleiotifiedcyrillic: "0469", - yusmallhiragana: "3085", - yusmallkatakana: "30E5", - yusmallkatakanahalfwidth: "FF6D", - yuyekorean: "318B", - yuyeokorean: "318A", - yyabengali: "09DF", - yyadeva: "095F", - z: "007A", - zaarmenian: "0566", - zacute: "017A", - zadeva: "095B", - zagurmukhi: "0A5B", - zaharabic: "0638", - zahfinalarabic: "FEC6", - zahinitialarabic: "FEC7", - zahiragana: "3056", - zahmedialarabic: "FEC8", - zainarabic: "0632", - zainfinalarabic: "FEB0", - zakatakana: "30B6", - zaqefgadolhebrew: "0595", - zaqefqatanhebrew: "0594", - zarqahebrew: "0598", - zayin: "05D6", - zayindagesh: "FB36", - zayindageshhebrew: "FB36", - zayinhebrew: "05D6", - zbopomofo: "3117", - zcaron: "017E", - zcircle: "24E9", - zcircumflex: "1E91", - zcurl: "0291", - zdot: "017C", - zdotaccent: "017C", - zdotbelow: "1E93", - zecyrillic: "0437", - zedescendercyrillic: "0499", - zedieresiscyrillic: "04DF", - zehiragana: "305C", - zekatakana: "30BC", - zero: "0030", - zeroarabic: "0660", - zerobengali: "09E6", - zerodeva: "0966", - zerogujarati: "0AE6", - zerogurmukhi: "0A66", - zerohackarabic: "0660", - zeroinferior: "2080", - zeromonospace: "FF10", - zerooldstyle: "F730", - zeropersian: "06F0", - zerosuperior: "2070", - zerothai: "0E50", - zerowidthjoiner: "FEFF", - zerowidthnonjoiner: "200C", - zerowidthspace: "200B", - zeta: "03B6", - zhbopomofo: "3113", - zhearmenian: "056A", - zhebrevecyrillic: "04C2", - zhecyrillic: "0436", - zhedescendercyrillic: "0497", - zhedieresiscyrillic: "04DD", - zihiragana: "3058", - zikatakana: "30B8", - zinorhebrew: "05AE", - zlinebelow: "1E95", - zmonospace: "FF5A", - zohiragana: "305E", - zokatakana: "30BE", - zparen: "24B5", - zretroflexhook: "0290", - zstroke: "01B6", - zuhiragana: "305A", - zukatakana: "30BA" + 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"] = "3008"; -GlyphsUnicode["angbracketright"] = "3009"; -GlyphsUnicode["circlecopyrt"] = "00A9"; +GlyphsUnicode["angbracketleft"] = 0x3008; +GlyphsUnicode["angbracketright"] = 0x3009; +GlyphsUnicode["circlecopyrt"] = 0x00A9; From 995c825cc5574a291633fb22977058a057ab7d46 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Fri, 17 Jun 2011 00:46:27 -0700 Subject: [PATCH 75/77] revert commit 2311c954f8b74297725bda9e90e3eabf79862193 --- fonts.js | 2 +- glyphlist.js | 8406 +++++++++++++++++++++++++------------------------- 2 files changed, 4204 insertions(+), 4204 deletions(-) diff --git a/fonts.js b/fonts.js index e64001155..2db7e745f 100644 --- a/fonts.js +++ b/fonts.js @@ -40,7 +40,7 @@ var Fonts = { unicodeFromCode: function fonts_unicodeFromCode(aCode) { var unicode = GlyphsUnicode[this.active.encoding[aCode]]; - return unicode ? unicode : aCode; + return unicode ? "0x" + unicode : aCode; } }; diff --git a/glyphlist.js b/glyphlist.js index f5a11b522..e147f6c8a 100644 --- a/glyphlist.js +++ b/glyphlist.js @@ -1,1510 +1,1510 @@ 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, + A: "0041", + AE: "00C6", + AEacute: "01FC", + AEmacron: "01E2", + AEsmall: "F7E6", + Aacute: "00C1", + Aacutesmall: "F7E1", + Abreve: "0102", + Abreveacute: "1EAE", + Abrevecyrillic: "04D0", + Abrevedotbelow: "1EB6", + Abrevegrave: "1EB0", + Abrevehookabove: "1EB2", + Abrevetilde: "1EB4", + Acaron: "01CD", + Acircle: "24B6", + Acircumflex: "00C2", + Acircumflexacute: "1EA4", + Acircumflexdotbelow: "1EAC", + Acircumflexgrave: "1EA6", + Acircumflexhookabove: "1EA8", + Acircumflexsmall: "F7E2", + Acircumflextilde: "1EAA", + Acute: "F6C9", + Acutesmall: "F7B4", + Acyrillic: "0410", + Adblgrave: "0200", + Adieresis: "00C4", + Adieresiscyrillic: "04D2", + Adieresismacron: "01DE", + Adieresissmall: "F7E4", + Adotbelow: "1EA0", + Adotmacron: "01E0", + Agrave: "00C0", + Agravesmall: "F7E0", + Ahookabove: "1EA2", + Aiecyrillic: "04D4", + Ainvertedbreve: "0202", + Alpha: "0391", + Alphatonos: "0386", + Amacron: "0100", + Amonospace: "FF21", + Aogonek: "0104", + Aring: "00C5", + Aringacute: "01FA", + Aringbelow: "1E00", + Aringsmall: "F7E5", + Asmall: "F761", + Atilde: "00C3", + Atildesmall: "F7E3", + Aybarmenian: "0531", + B: "0042", + Bcircle: "24B7", + Bdotaccent: "1E02", + Bdotbelow: "1E04", + Becyrillic: "0411", + Benarmenian: "0532", + Beta: "0392", + Bhook: "0181", + Blinebelow: "1E06", + Bmonospace: "FF22", + Brevesmall: "F6F4", + Bsmall: "F762", + Btopbar: "0182", + C: "0043", + Caarmenian: "053E", + Cacute: "0106", + Caron: "F6CA", + Caronsmall: "F6F5", + Ccaron: "010C", + Ccedilla: "00C7", + Ccedillaacute: "1E08", + Ccedillasmall: "F7E7", + Ccircle: "24B8", + Ccircumflex: "0108", + Cdot: "010A", + Cdotaccent: "010A", + Cedillasmall: "F7B8", + Chaarmenian: "0549", + Cheabkhasiancyrillic: "04BC", + Checyrillic: "0427", + Chedescenderabkhasiancyrillic: "04BE", + Chedescendercyrillic: "04B6", + Chedieresiscyrillic: "04F4", + Cheharmenian: "0543", + Chekhakassiancyrillic: "04CB", + Cheverticalstrokecyrillic: "04B8", + Chi: "03A7", + Chook: "0187", + Circumflexsmall: "F6F6", + Cmonospace: "FF23", + Coarmenian: "0551", + Csmall: "F763", + D: "0044", + DZ: "01F1", + DZcaron: "01C4", + Daarmenian: "0534", + Dafrican: "0189", + Dcaron: "010E", + Dcedilla: "1E10", + Dcircle: "24B9", + Dcircumflexbelow: "1E12", + Dcroat: "0110", + Ddotaccent: "1E0A", + Ddotbelow: "1E0C", + Decyrillic: "0414", + Deicoptic: "03EE", + Delta: "2206", + Deltagreek: "0394", + Dhook: "018A", + Dieresis: "F6CB", + DieresisAcute: "F6CC", + DieresisGrave: "F6CD", + Dieresissmall: "F7A8", + Digammagreek: "03DC", + Djecyrillic: "0402", + Dlinebelow: "1E0E", + Dmonospace: "FF24", + Dotaccentsmall: "F6F7", + Dslash: "0110", + Dsmall: "F764", + Dtopbar: "018B", + Dz: "01F2", + Dzcaron: "01C5", + Dzeabkhasiancyrillic: "04E0", + Dzecyrillic: "0405", + Dzhecyrillic: "040F", + E: "0045", + Eacute: "00C9", + Eacutesmall: "F7E9", + Ebreve: "0114", + Ecaron: "011A", + Ecedillabreve: "1E1C", + Echarmenian: "0535", + Ecircle: "24BA", + Ecircumflex: "00CA", + Ecircumflexacute: "1EBE", + Ecircumflexbelow: "1E18", + Ecircumflexdotbelow: "1EC6", + Ecircumflexgrave: "1EC0", + Ecircumflexhookabove: "1EC2", + Ecircumflexsmall: "F7EA", + Ecircumflextilde: "1EC4", + Ecyrillic: "0404", + Edblgrave: "0204", + Edieresis: "00CB", + Edieresissmall: "F7EB", + Edot: "0116", + Edotaccent: "0116", + Edotbelow: "1EB8", + Efcyrillic: "0424", + Egrave: "00C8", + Egravesmall: "F7E8", + Eharmenian: "0537", + Ehookabove: "1EBA", + Eightroman: "2167", + Einvertedbreve: "0206", + Eiotifiedcyrillic: "0464", + Elcyrillic: "041B", + Elevenroman: "216A", + Emacron: "0112", + Emacronacute: "1E16", + Emacrongrave: "1E14", + Emcyrillic: "041C", + Emonospace: "FF25", + Encyrillic: "041D", + Endescendercyrillic: "04A2", + Eng: "014A", + Enghecyrillic: "04A4", + Enhookcyrillic: "04C7", + Eogonek: "0118", + Eopen: "0190", + Epsilon: "0395", + Epsilontonos: "0388", + Ercyrillic: "0420", + Ereversed: "018E", + Ereversedcyrillic: "042D", + Escyrillic: "0421", + Esdescendercyrillic: "04AA", + Esh: "01A9", + Esmall: "F765", + Eta: "0397", + Etarmenian: "0538", + Etatonos: "0389", + Eth: "00D0", + Ethsmall: "F7F0", + Etilde: "1EBC", + Etildebelow: "1E1A", + Euro: "20AC", + Ezh: "01B7", + Ezhcaron: "01EE", + Ezhreversed: "01B8", + F: "0046", + Fcircle: "24BB", + Fdotaccent: "1E1E", + Feharmenian: "0556", + Feicoptic: "03E4", + Fhook: "0191", + Fitacyrillic: "0472", + Fiveroman: "2164", + Fmonospace: "FF26", + Fourroman: "2163", + Fsmall: "F766", + G: "0047", + GBsquare: "3387", + Gacute: "01F4", + Gamma: "0393", + Gammaafrican: "0194", + Gangiacoptic: "03EA", + Gbreve: "011E", + Gcaron: "01E6", + Gcedilla: "0122", + Gcircle: "24BC", + Gcircumflex: "011C", + Gcommaaccent: "0122", + Gdot: "0120", + Gdotaccent: "0120", + Gecyrillic: "0413", + Ghadarmenian: "0542", + Ghemiddlehookcyrillic: "0494", + Ghestrokecyrillic: "0492", + Gheupturncyrillic: "0490", + Ghook: "0193", + Gimarmenian: "0533", + Gjecyrillic: "0403", + Gmacron: "1E20", + Gmonospace: "FF27", + Grave: "F6CE", + Gravesmall: "F760", + Gsmall: "F767", + Gsmallhook: "029B", + Gstroke: "01E4", + H: "0048", + H18533: "25CF", + H18543: "25AA", + H18551: "25AB", + H22073: "25A1", + HPsquare: "33CB", + Haabkhasiancyrillic: "04A8", + Hadescendercyrillic: "04B2", + Hardsigncyrillic: "042A", + Hbar: "0126", + Hbrevebelow: "1E2A", + Hcedilla: "1E28", + Hcircle: "24BD", + Hcircumflex: "0124", + Hdieresis: "1E26", + Hdotaccent: "1E22", + Hdotbelow: "1E24", + Hmonospace: "FF28", + Hoarmenian: "0540", + Horicoptic: "03E8", + Hsmall: "F768", + Hungarumlaut: "F6CF", + Hungarumlautsmall: "F6F8", + Hzsquare: "3390", + I: "0049", + IAcyrillic: "042F", + IJ: "0132", + IUcyrillic: "042E", + Iacute: "00CD", + Iacutesmall: "F7ED", + Ibreve: "012C", + Icaron: "01CF", + Icircle: "24BE", + Icircumflex: "00CE", + Icircumflexsmall: "F7EE", + Icyrillic: "0406", + Idblgrave: "0208", + Idieresis: "00CF", + Idieresisacute: "1E2E", + Idieresiscyrillic: "04E4", + Idieresissmall: "F7EF", + Idot: "0130", + Idotaccent: "0130", + Idotbelow: "1ECA", + Iebrevecyrillic: "04D6", + Iecyrillic: "0415", + Ifraktur: "2111", + Igrave: "00CC", + Igravesmall: "F7EC", + Ihookabove: "1EC8", + Iicyrillic: "0418", + Iinvertedbreve: "020A", + Iishortcyrillic: "0419", + Imacron: "012A", + Imacroncyrillic: "04E2", + Imonospace: "FF29", + Iniarmenian: "053B", + Iocyrillic: "0401", + Iogonek: "012E", + Iota: "0399", + Iotaafrican: "0196", + Iotadieresis: "03AA", + Iotatonos: "038A", + Ismall: "F769", + Istroke: "0197", + Itilde: "0128", + Itildebelow: "1E2C", + Izhitsacyrillic: "0474", + Izhitsadblgravecyrillic: "0476", + J: "004A", + Jaarmenian: "0541", + Jcircle: "24BF", + Jcircumflex: "0134", + Jecyrillic: "0408", + Jheharmenian: "054B", + Jmonospace: "FF2A", + Jsmall: "F76A", + K: "004B", + KBsquare: "3385", + KKsquare: "33CD", + Kabashkircyrillic: "04A0", + Kacute: "1E30", + Kacyrillic: "041A", + Kadescendercyrillic: "049A", + Kahookcyrillic: "04C3", + Kappa: "039A", + Kastrokecyrillic: "049E", + Kaverticalstrokecyrillic: "049C", + Kcaron: "01E8", + Kcedilla: "0136", + Kcircle: "24C0", + Kcommaaccent: "0136", + Kdotbelow: "1E32", + Keharmenian: "0554", + Kenarmenian: "053F", + Khacyrillic: "0425", + Kheicoptic: "03E6", + Khook: "0198", + Kjecyrillic: "040C", + Klinebelow: "1E34", + Kmonospace: "FF2B", + Koppacyrillic: "0480", + Koppagreek: "03DE", + Ksicyrillic: "046E", + Ksmall: "F76B", + L: "004C", + LJ: "01C7", + LL: "F6BF", + Lacute: "0139", + Lambda: "039B", + Lcaron: "013D", + Lcedilla: "013B", + Lcircle: "24C1", + Lcircumflexbelow: "1E3C", + Lcommaaccent: "013B", + Ldot: "013F", + Ldotaccent: "013F", + Ldotbelow: "1E36", + Ldotbelowmacron: "1E38", + Liwnarmenian: "053C", + Lj: "01C8", + Ljecyrillic: "0409", + Llinebelow: "1E3A", + Lmonospace: "FF2C", + Lslash: "0141", + Lslashsmall: "F6F9", + Lsmall: "F76C", + M: "004D", + MBsquare: "3386", + Macron: "F6D0", + Macronsmall: "F7AF", + Macute: "1E3E", + Mcircle: "24C2", + Mdotaccent: "1E40", + Mdotbelow: "1E42", + Menarmenian: "0544", + Mmonospace: "FF2D", + Msmall: "F76D", + Mturned: "019C", + Mu: "039C", + N: "004E", + NJ: "01CA", + Nacute: "0143", + Ncaron: "0147", + Ncedilla: "0145", + Ncircle: "24C3", + Ncircumflexbelow: "1E4A", + Ncommaaccent: "0145", + Ndotaccent: "1E44", + Ndotbelow: "1E46", + Nhookleft: "019D", + Nineroman: "2168", + Nj: "01CB", + Njecyrillic: "040A", + Nlinebelow: "1E48", + Nmonospace: "FF2E", + Nowarmenian: "0546", + Nsmall: "F76E", + Ntilde: "00D1", + Ntildesmall: "F7F1", + Nu: "039D", + O: "004F", + OE: "0152", + OEsmall: "F6FA", + Oacute: "00D3", + Oacutesmall: "F7F3", + Obarredcyrillic: "04E8", + Obarreddieresiscyrillic: "04EA", + Obreve: "014E", + Ocaron: "01D1", + Ocenteredtilde: "019F", + Ocircle: "24C4", + Ocircumflex: "00D4", + Ocircumflexacute: "1ED0", + Ocircumflexdotbelow: "1ED8", + Ocircumflexgrave: "1ED2", + Ocircumflexhookabove: "1ED4", + Ocircumflexsmall: "F7F4", + Ocircumflextilde: "1ED6", + Ocyrillic: "041E", + Odblacute: "0150", + Odblgrave: "020C", + Odieresis: "00D6", + Odieresiscyrillic: "04E6", + Odieresissmall: "F7F6", + Odotbelow: "1ECC", + Ogoneksmall: "F6FB", + Ograve: "00D2", + Ogravesmall: "F7F2", + Oharmenian: "0555", + Ohm: "2126", + Ohookabove: "1ECE", + Ohorn: "01A0", + Ohornacute: "1EDA", + Ohorndotbelow: "1EE2", + Ohorngrave: "1EDC", + Ohornhookabove: "1EDE", + Ohorntilde: "1EE0", + Ohungarumlaut: "0150", + Oi: "01A2", + Oinvertedbreve: "020E", + Omacron: "014C", + Omacronacute: "1E52", + Omacrongrave: "1E50", + Omega: "2126", + Omegacyrillic: "0460", + Omegagreek: "03A9", + Omegaroundcyrillic: "047A", + Omegatitlocyrillic: "047C", + Omegatonos: "038F", + Omicron: "039F", + Omicrontonos: "038C", + Omonospace: "FF2F", + Oneroman: "2160", + Oogonek: "01EA", + Oogonekmacron: "01EC", + Oopen: "0186", + Oslash: "00D8", + Oslashacute: "01FE", + Oslashsmall: "F7F8", + Osmall: "F76F", + Ostrokeacute: "01FE", + Otcyrillic: "047E", + Otilde: "00D5", + Otildeacute: "1E4C", + Otildedieresis: "1E4E", + Otildesmall: "F7F5", + P: "0050", + Pacute: "1E54", + Pcircle: "24C5", + Pdotaccent: "1E56", + Pecyrillic: "041F", + Peharmenian: "054A", + Pemiddlehookcyrillic: "04A6", + Phi: "03A6", + Phook: "01A4", + Pi: "03A0", + Piwrarmenian: "0553", + Pmonospace: "FF30", + Psi: "03A8", + Psicyrillic: "0470", + Psmall: "F770", + Q: "0051", + Qcircle: "24C6", + Qmonospace: "FF31", + Qsmall: "F771", + R: "0052", + Raarmenian: "054C", + Racute: "0154", + Rcaron: "0158", + Rcedilla: "0156", + Rcircle: "24C7", + Rcommaaccent: "0156", + Rdblgrave: "0210", + Rdotaccent: "1E58", + Rdotbelow: "1E5A", + Rdotbelowmacron: "1E5C", + Reharmenian: "0550", + Rfraktur: "211C", + Rho: "03A1", + Ringsmall: "F6FC", + Rinvertedbreve: "0212", + Rlinebelow: "1E5E", + Rmonospace: "FF32", + Rsmall: "F772", + Rsmallinverted: "0281", + Rsmallinvertedsuperior: "02B6", + S: "0053", + SF010000: "250C", + SF020000: "2514", + SF030000: "2510", + SF040000: "2518", + SF050000: "253C", + SF060000: "252C", + SF070000: "2534", + SF080000: "251C", + SF090000: "2524", + SF100000: "2500", + SF110000: "2502", + SF190000: "2561", + SF200000: "2562", + SF210000: "2556", + SF220000: "2555", + SF230000: "2563", + SF240000: "2551", + SF250000: "2557", + SF260000: "255D", + SF270000: "255C", + SF280000: "255B", + SF360000: "255E", + SF370000: "255F", + SF380000: "255A", + SF390000: "2554", + SF400000: "2569", + SF410000: "2566", + SF420000: "2560", + SF430000: "2550", + SF440000: "256C", + SF450000: "2567", + SF460000: "2568", + SF470000: "2564", + SF480000: "2565", + SF490000: "2559", + SF500000: "2558", + SF510000: "2552", + SF520000: "2553", + SF530000: "256B", + SF540000: "256A", + Sacute: "015A", + Sacutedotaccent: "1E64", + Sampigreek: "03E0", + Scaron: "0160", + Scarondotaccent: "1E66", + Scaronsmall: "F6FD", + Scedilla: "015E", + Schwa: "018F", + Schwacyrillic: "04D8", + Schwadieresiscyrillic: "04DA", + Scircle: "24C8", + Scircumflex: "015C", + Scommaaccent: "0218", + Sdotaccent: "1E60", + Sdotbelow: "1E62", + Sdotbelowdotaccent: "1E68", + Seharmenian: "054D", + Sevenroman: "2166", + Shaarmenian: "0547", + Shacyrillic: "0428", + Shchacyrillic: "0429", + Sheicoptic: "03E2", + Shhacyrillic: "04BA", + Shimacoptic: "03EC", + Sigma: "03A3", + Sixroman: "2165", + Smonospace: "FF33", + Softsigncyrillic: "042C", + Ssmall: "F773", + Stigmagreek: "03DA", + T: "0054", + Tau: "03A4", + Tbar: "0166", + Tcaron: "0164", + Tcedilla: "0162", + Tcircle: "24C9", + Tcircumflexbelow: "1E70", + Tcommaaccent: "0162", + Tdotaccent: "1E6A", + Tdotbelow: "1E6C", + Tecyrillic: "0422", + Tedescendercyrillic: "04AC", + Tenroman: "2169", + Tetsecyrillic: "04B4", + Theta: "0398", + Thook: "01AC", + Thorn: "00DE", + Thornsmall: "F7FE", + Threeroman: "2162", + Tildesmall: "F6FE", + Tiwnarmenian: "054F", + Tlinebelow: "1E6E", + Tmonospace: "FF34", + Toarmenian: "0539", + Tonefive: "01BC", + Tonesix: "0184", + Tonetwo: "01A7", + Tretroflexhook: "01AE", + Tsecyrillic: "0426", + Tshecyrillic: "040B", + Tsmall: "F774", + Twelveroman: "216B", + Tworoman: "2161", + U: "0055", + Uacute: "00DA", + Uacutesmall: "F7FA", + Ubreve: "016C", + Ucaron: "01D3", + Ucircle: "24CA", + Ucircumflex: "00DB", + Ucircumflexbelow: "1E76", + Ucircumflexsmall: "F7FB", + Ucyrillic: "0423", + Udblacute: "0170", + Udblgrave: "0214", + Udieresis: "00DC", + Udieresisacute: "01D7", + Udieresisbelow: "1E72", + Udieresiscaron: "01D9", + Udieresiscyrillic: "04F0", + Udieresisgrave: "01DB", + Udieresismacron: "01D5", + Udieresissmall: "F7FC", + Udotbelow: "1EE4", + Ugrave: "00D9", + Ugravesmall: "F7F9", + Uhookabove: "1EE6", + Uhorn: "01AF", + Uhornacute: "1EE8", + Uhorndotbelow: "1EF0", + Uhorngrave: "1EEA", + Uhornhookabove: "1EEC", + Uhorntilde: "1EEE", + Uhungarumlaut: "0170", + Uhungarumlautcyrillic: "04F2", + Uinvertedbreve: "0216", + Ukcyrillic: "0478", + Umacron: "016A", + Umacroncyrillic: "04EE", + Umacrondieresis: "1E7A", + Umonospace: "FF35", + Uogonek: "0172", + Upsilon: "03A5", + Upsilon1: "03D2", + Upsilonacutehooksymbolgreek: "03D3", + Upsilonafrican: "01B1", + Upsilondieresis: "03AB", + Upsilondieresishooksymbolgreek: "03D4", + Upsilonhooksymbol: "03D2", + Upsilontonos: "038E", + Uring: "016E", + Ushortcyrillic: "040E", + Usmall: "F775", + Ustraightcyrillic: "04AE", + Ustraightstrokecyrillic: "04B0", + Utilde: "0168", + Utildeacute: "1E78", + Utildebelow: "1E74", + V: "0056", + Vcircle: "24CB", + Vdotbelow: "1E7E", + Vecyrillic: "0412", + Vewarmenian: "054E", + Vhook: "01B2", + Vmonospace: "FF36", + Voarmenian: "0548", + Vsmall: "F776", + Vtilde: "1E7C", + W: "0057", + Wacute: "1E82", + Wcircle: "24CC", + Wcircumflex: "0174", + Wdieresis: "1E84", + Wdotaccent: "1E86", + Wdotbelow: "1E88", + Wgrave: "1E80", + Wmonospace: "FF37", + Wsmall: "F777", + X: "0058", + Xcircle: "24CD", + Xdieresis: "1E8C", + Xdotaccent: "1E8A", + Xeharmenian: "053D", + Xi: "039E", + Xmonospace: "FF38", + Xsmall: "F778", + Y: "0059", + Yacute: "00DD", + Yacutesmall: "F7FD", + Yatcyrillic: "0462", + Ycircle: "24CE", + Ycircumflex: "0176", + Ydieresis: "0178", + Ydieresissmall: "F7FF", + Ydotaccent: "1E8E", + Ydotbelow: "1EF4", + Yericyrillic: "042B", + Yerudieresiscyrillic: "04F8", + Ygrave: "1EF2", + Yhook: "01B3", + Yhookabove: "1EF6", + Yiarmenian: "0545", + Yicyrillic: "0407", + Yiwnarmenian: "0552", + Ymonospace: "FF39", + Ysmall: "F779", + Ytilde: "1EF8", + Yusbigcyrillic: "046A", + Yusbigiotifiedcyrillic: "046C", + Yuslittlecyrillic: "0466", + Yuslittleiotifiedcyrillic: "0468", + Z: "005A", + Zaarmenian: "0536", + Zacute: "0179", + Zcaron: "017D", + Zcaronsmall: "F6FF", + Zcircle: "24CF", + Zcircumflex: "1E90", + Zdot: "017B", + Zdotaccent: "017B", + Zdotbelow: "1E92", + Zecyrillic: "0417", + Zedescendercyrillic: "0498", + Zedieresiscyrillic: "04DE", + Zeta: "0396", + Zhearmenian: "053A", + Zhebrevecyrillic: "04C1", + Zhecyrillic: "0416", + Zhedescendercyrillic: "0496", + Zhedieresiscyrillic: "04DC", + Zlinebelow: "1E94", + Zmonospace: "FF3A", + Zsmall: "F77A", + Zstroke: "01B5", + a: "0061", + aabengali: "0986", + aacute: "00E1", + aadeva: "0906", + aagujarati: "0A86", + aagurmukhi: "0A06", + aamatragurmukhi: "0A3E", + aarusquare: "3303", + aavowelsignbengali: "09BE", + aavowelsigndeva: "093E", + aavowelsigngujarati: "0ABE", + abbreviationmarkarmenian: "055F", + abbreviationsigndeva: "0970", + abengali: "0985", + abopomofo: "311A", + abreve: "0103", + abreveacute: "1EAF", + abrevecyrillic: "04D1", + abrevedotbelow: "1EB7", + abrevegrave: "1EB1", + abrevehookabove: "1EB3", + abrevetilde: "1EB5", + acaron: "01CE", + acircle: "24D0", + acircumflex: "00E2", + acircumflexacute: "1EA5", + acircumflexdotbelow: "1EAD", + acircumflexgrave: "1EA7", + acircumflexhookabove: "1EA9", + acircumflextilde: "1EAB", + acute: "00B4", + acutebelowcmb: "0317", + acutecmb: "0301", + acutecomb: "0301", + acutedeva: "0954", + acutelowmod: "02CF", + acutetonecmb: "0341", + acyrillic: "0430", + adblgrave: "0201", + addakgurmukhi: "0A71", + adeva: "0905", + adieresis: "00E4", + adieresiscyrillic: "04D3", + adieresismacron: "01DF", + adotbelow: "1EA1", + adotmacron: "01E1", + ae: "00E6", + aeacute: "01FD", + aekorean: "3150", + aemacron: "01E3", + afii00208: "2015", + afii08941: "20A4", + afii10017: "0410", + afii10018: "0411", + afii10019: "0412", + afii10020: "0413", + afii10021: "0414", + afii10022: "0415", + afii10023: "0401", + afii10024: "0416", + afii10025: "0417", + afii10026: "0418", + afii10027: "0419", + afii10028: "041A", + afii10029: "041B", + afii10030: "041C", + afii10031: "041D", + afii10032: "041E", + afii10033: "041F", + afii10034: "0420", + afii10035: "0421", + afii10036: "0422", + afii10037: "0423", + afii10038: "0424", + afii10039: "0425", + afii10040: "0426", + afii10041: "0427", + afii10042: "0428", + afii10043: "0429", + afii10044: "042A", + afii10045: "042B", + afii10046: "042C", + afii10047: "042D", + afii10048: "042E", + afii10049: "042F", + afii10050: "0490", + afii10051: "0402", + afii10052: "0403", + afii10053: "0404", + afii10054: "0405", + afii10055: "0406", + afii10056: "0407", + afii10057: "0408", + afii10058: "0409", + afii10059: "040A", + afii10060: "040B", + afii10061: "040C", + afii10062: "040E", + afii10063: "F6C4", + afii10064: "F6C5", + afii10065: "0430", + afii10066: "0431", + afii10067: "0432", + afii10068: "0433", + afii10069: "0434", + afii10070: "0435", + afii10071: "0451", + afii10072: "0436", + afii10073: "0437", + afii10074: "0438", + afii10075: "0439", + afii10076: "043A", + afii10077: "043B", + afii10078: "043C", + afii10079: "043D", + afii10080: "043E", + afii10081: "043F", + afii10082: "0440", + afii10083: "0441", + afii10084: "0442", + afii10085: "0443", + afii10086: "0444", + afii10087: "0445", + afii10088: "0446", + afii10089: "0447", + afii10090: "0448", + afii10091: "0449", + afii10092: "044A", + afii10093: "044B", + afii10094: "044C", + afii10095: "044D", + afii10096: "044E", + afii10097: "044F", + afii10098: "0491", + afii10099: "0452", + afii10100: "0453", + afii10101: "0454", + afii10102: "0455", + afii10103: "0456", + afii10104: "0457", + afii10105: "0458", + afii10106: "0459", + afii10107: "045A", + afii10108: "045B", + afii10109: "045C", + afii10110: "045E", + afii10145: "040F", + afii10146: "0462", + afii10147: "0472", + afii10148: "0474", + afii10192: "F6C6", + afii10193: "045F", + afii10194: "0463", + afii10195: "0473", + afii10196: "0475", + afii10831: "F6C7", + afii10832: "F6C8", + afii10846: "04D9", + afii299: "200E", + afii300: "200F", + afii301: "200D", + afii57381: "066A", + afii57388: "060C", + afii57392: "0660", + afii57393: "0661", + afii57394: "0662", + afii57395: "0663", + afii57396: "0664", + afii57397: "0665", + afii57398: "0666", + afii57399: "0667", + afii57400: "0668", + afii57401: "0669", + afii57403: "061B", + afii57407: "061F", + afii57409: "0621", + afii57410: "0622", + afii57411: "0623", + afii57412: "0624", + afii57413: "0625", + afii57414: "0626", + afii57415: "0627", + afii57416: "0628", + afii57417: "0629", + afii57418: "062A", + afii57419: "062B", + afii57420: "062C", + afii57421: "062D", + afii57422: "062E", + afii57423: "062F", + afii57424: "0630", + afii57425: "0631", + afii57426: "0632", + afii57427: "0633", + afii57428: "0634", + afii57429: "0635", + afii57430: "0636", + afii57431: "0637", + afii57432: "0638", + afii57433: "0639", + afii57434: "063A", + afii57440: "0640", + afii57441: "0641", + afii57442: "0642", + afii57443: "0643", + afii57444: "0644", + afii57445: "0645", + afii57446: "0646", + afii57448: "0648", + afii57449: "0649", + afii57450: "064A", + afii57451: "064B", + afii57452: "064C", + afii57453: "064D", + afii57454: "064E", + afii57455: "064F", + afii57456: "0650", + afii57457: "0651", + afii57458: "0652", + afii57470: "0647", + afii57505: "06A4", + afii57506: "067E", + afii57507: "0686", + afii57508: "0698", + afii57509: "06AF", + afii57511: "0679", + afii57512: "0688", + afii57513: "0691", + afii57514: "06BA", + afii57519: "06D2", + afii57534: "06D5", + afii57636: "20AA", + afii57645: "05BE", + afii57658: "05C3", + afii57664: "05D0", + afii57665: "05D1", + afii57666: "05D2", + afii57667: "05D3", + afii57668: "05D4", + afii57669: "05D5", + afii57670: "05D6", + afii57671: "05D7", + afii57672: "05D8", + afii57673: "05D9", + afii57674: "05DA", + afii57675: "05DB", + afii57676: "05DC", + afii57677: "05DD", + afii57678: "05DE", + afii57679: "05DF", + afii57680: "05E0", + afii57681: "05E1", + afii57682: "05E2", + afii57683: "05E3", + afii57684: "05E4", + afii57685: "05E5", + afii57686: "05E6", + afii57687: "05E7", + afii57688: "05E8", + afii57689: "05E9", + afii57690: "05EA", + afii57694: "FB2A", + afii57695: "FB2B", + afii57700: "FB4B", + afii57705: "FB1F", + afii57716: "05F0", + afii57717: "05F1", + afii57718: "05F2", + afii57723: "FB35", + afii57793: "05B4", + afii57794: "05B5", + afii57795: "05B6", + afii57796: "05BB", + afii57797: "05B8", + afii57798: "05B7", + afii57799: "05B0", + afii57800: "05B2", + afii57801: "05B1", + afii57802: "05B3", + afii57803: "05C2", + afii57804: "05C1", + afii57806: "05B9", + afii57807: "05BC", + afii57839: "05BD", + afii57841: "05BF", + afii57842: "05C0", + afii57929: "02BC", + afii61248: "2105", + afii61289: "2113", + afii61352: "2116", + afii61573: "202C", + afii61574: "202D", + afii61575: "202E", + afii61664: "200C", + afii63167: "066D", + afii64937: "02BD", + agrave: "00E0", + agujarati: "0A85", + agurmukhi: "0A05", + ahiragana: "3042", + ahookabove: "1EA3", + aibengali: "0990", + aibopomofo: "311E", + aideva: "0910", + aiecyrillic: "04D5", + aigujarati: "0A90", + aigurmukhi: "0A10", + aimatragurmukhi: "0A48", + ainarabic: "0639", + ainfinalarabic: "FECA", + aininitialarabic: "FECB", + ainmedialarabic: "FECC", + ainvertedbreve: "0203", + aivowelsignbengali: "09C8", + aivowelsigndeva: "0948", + aivowelsigngujarati: "0AC8", + akatakana: "30A2", + akatakanahalfwidth: "FF71", + akorean: "314F", + alef: "05D0", + alefarabic: "0627", + alefdageshhebrew: "FB30", + aleffinalarabic: "FE8E", + alefhamzaabovearabic: "0623", + alefhamzaabovefinalarabic: "FE84", + alefhamzabelowarabic: "0625", + alefhamzabelowfinalarabic: "FE88", + alefhebrew: "05D0", + aleflamedhebrew: "FB4F", + alefmaddaabovearabic: "0622", + alefmaddaabovefinalarabic: "FE82", + alefmaksuraarabic: "0649", + alefmaksurafinalarabic: "FEF0", + alefmaksurainitialarabic: "FEF3", + alefmaksuramedialarabic: "FEF4", + alefpatahhebrew: "FB2E", + alefqamatshebrew: "FB2F", + aleph: "2135", + allequal: "224C", + alpha: "03B1", + alphatonos: "03AC", + amacron: "0101", + amonospace: "FF41", + ampersand: "0026", + ampersandmonospace: "FF06", + ampersandsmall: "F726", + amsquare: "33C2", + anbopomofo: "3122", + angbopomofo: "3124", + angkhankhuthai: "0E5A", + angle: "2220", + anglebracketleft: "3008", + anglebracketleftvertical: "FE3F", + anglebracketright: "3009", + anglebracketrightvertical: "FE40", + angleleft: "2329", + angleright: "232A", + angstrom: "212B", + anoteleia: "0387", + anudattadeva: "0952", + anusvarabengali: "0982", + anusvaradeva: "0902", + anusvaragujarati: "0A82", + aogonek: "0105", + apaatosquare: "3300", + aparen: "249C", + apostrophearmenian: "055A", + apostrophemod: "02BC", + apple: "F8FF", + approaches: "2250", + approxequal: "2248", + approxequalorimage: "2252", + approximatelyequal: "2245", + araeaekorean: "318E", + araeakorean: "318D", + arc: "2312", + arighthalfring: "1E9A", + aring: "00E5", + aringacute: "01FB", + aringbelow: "1E01", + arrowboth: "2194", + arrowdashdown: "21E3", + arrowdashleft: "21E0", + arrowdashright: "21E2", + arrowdashup: "21E1", + arrowdblboth: "21D4", + arrowdbldown: "21D3", + arrowdblleft: "21D0", + arrowdblright: "21D2", + arrowdblup: "21D1", + arrowdown: "2193", + arrowdownleft: "2199", + arrowdownright: "2198", + arrowdownwhite: "21E9", + arrowheaddownmod: "02C5", + arrowheadleftmod: "02C2", + arrowheadrightmod: "02C3", + arrowheadupmod: "02C4", + arrowhorizex: "F8E7", + arrowleft: "2190", + arrowleftdbl: "21D0", + arrowleftdblstroke: "21CD", + arrowleftoverright: "21C6", + arrowleftwhite: "21E6", + arrowright: "2192", + arrowrightdblstroke: "21CF", + arrowrightheavy: "279E", + arrowrightoverleft: "21C4", + arrowrightwhite: "21E8", + arrowtableft: "21E4", + arrowtabright: "21E5", + arrowup: "2191", + arrowupdn: "2195", + arrowupdnbse: "21A8", + arrowupdownbase: "21A8", + arrowupleft: "2196", + arrowupleftofdown: "21C5", + arrowupright: "2197", + arrowupwhite: "21E7", + arrowvertex: "F8E6", + asciicircum: "005E", + asciicircummonospace: "FF3E", + asciitilde: "007E", + asciitildemonospace: "FF5E", + ascript: "0251", + ascriptturned: "0252", + asmallhiragana: "3041", + asmallkatakana: "30A1", + asmallkatakanahalfwidth: "FF67", + asterisk: "002A", + asteriskaltonearabic: "066D", + asteriskarabic: "066D", + asteriskmath: "2217", + asteriskmonospace: "FF0A", + asterisksmall: "FE61", + asterism: "2042", + asuperior: "F6E9", + asymptoticallyequal: "2243", + at: "0040", + atilde: "00E3", + atmonospace: "FF20", + atsmall: "FE6B", + aturned: "0250", + aubengali: "0994", + aubopomofo: "3120", + audeva: "0914", + augujarati: "0A94", + augurmukhi: "0A14", + aulengthmarkbengali: "09D7", + aumatragurmukhi: "0A4C", + auvowelsignbengali: "09CC", + auvowelsigndeva: "094C", + auvowelsigngujarati: "0ACC", + avagrahadeva: "093D", + aybarmenian: "0561", + ayin: "05E2", + ayinaltonehebrew: "FB20", + ayinhebrew: "05E2", + b: "0062", + babengali: "09AC", + backslash: "005C", + backslashmonospace: "FF3C", + badeva: "092C", + bagujarati: "0AAC", + bagurmukhi: "0A2C", + bahiragana: "3070", + bahtthai: "0E3F", + bakatakana: "30D0", + bar: "007C", + barmonospace: "FF5C", + bbopomofo: "3105", + bcircle: "24D1", + bdotaccent: "1E03", + bdotbelow: "1E05", + beamedsixteenthnotes: "266C", + because: "2235", + becyrillic: "0431", + beharabic: "0628", + behfinalarabic: "FE90", + behinitialarabic: "FE91", + behiragana: "3079", + behmedialarabic: "FE92", + behmeeminitialarabic: "FC9F", + behmeemisolatedarabic: "FC08", + behnoonfinalarabic: "FC6D", + bekatakana: "30D9", + benarmenian: "0562", + bet: "05D1", + beta: "03B2", + betasymbolgreek: "03D0", + betdagesh: "FB31", + betdageshhebrew: "FB31", + bethebrew: "05D1", + betrafehebrew: "FB4C", + bhabengali: "09AD", + bhadeva: "092D", + bhagujarati: "0AAD", + bhagurmukhi: "0A2D", + bhook: "0253", + bihiragana: "3073", + bikatakana: "30D3", + bilabialclick: "0298", + bindigurmukhi: "0A02", + birusquare: "3331", + blackcircle: "25CF", + blackdiamond: "25C6", + blackdownpointingtriangle: "25BC", + blackleftpointingpointer: "25C4", + blackleftpointingtriangle: "25C0", + blacklenticularbracketleft: "3010", + blacklenticularbracketleftvertical: "FE3B", + blacklenticularbracketright: "3011", + blacklenticularbracketrightvertical: "FE3C", + blacklowerlefttriangle: "25E3", + blacklowerrighttriangle: "25E2", + blackrectangle: "25AC", + blackrightpointingpointer: "25BA", + blackrightpointingtriangle: "25B6", + blacksmallsquare: "25AA", + blacksmilingface: "263B", + blacksquare: "25A0", + blackstar: "2605", + blackupperlefttriangle: "25E4", + blackupperrighttriangle: "25E5", + blackuppointingsmalltriangle: "25B4", + blackuppointingtriangle: "25B2", + blank: "2423", + blinebelow: "1E07", + block: "2588", + bmonospace: "FF42", + bobaimaithai: "0E1A", + bohiragana: "307C", + bokatakana: "30DC", + bparen: "249D", + bqsquare: "33C3", + braceex: "F8F4", + braceleft: "007B", + braceleftbt: "F8F3", + braceleftmid: "F8F2", + braceleftmonospace: "FF5B", + braceleftsmall: "FE5B", + bracelefttp: "F8F1", + braceleftvertical: "FE37", + braceright: "007D", + bracerightbt: "F8FE", + bracerightmid: "F8FD", + bracerightmonospace: "FF5D", + bracerightsmall: "FE5C", + bracerighttp: "F8FC", + bracerightvertical: "FE38", + bracketleft: "005B", + bracketleftbt: "F8F0", + bracketleftex: "F8EF", + bracketleftmonospace: "FF3B", + bracketlefttp: "F8EE", + bracketright: "005D", + bracketrightbt: "F8FB", + bracketrightex: "F8FA", + bracketrightmonospace: "FF3D", + bracketrighttp: "F8F9", + breve: "02D8", + brevebelowcmb: "032E", + brevecmb: "0306", + breveinvertedbelowcmb: "032F", + breveinvertedcmb: "0311", + breveinverteddoublecmb: "0361", + bridgebelowcmb: "032A", + bridgeinvertedbelowcmb: "033A", + brokenbar: "00A6", + bstroke: "0180", + bsuperior: "F6EA", + btopbar: "0183", + buhiragana: "3076", + bukatakana: "30D6", + bullet: "2022", + bulletinverse: "25D8", + bulletoperator: "2219", + bullseye: "25CE", + c: "0063", + caarmenian: "056E", + cabengali: "099A", + cacute: "0107", + cadeva: "091A", + cagujarati: "0A9A", + cagurmukhi: "0A1A", + calsquare: "3388", + candrabindubengali: "0981", + candrabinducmb: "0310", + candrabindudeva: "0901", + candrabindugujarati: "0A81", + capslock: "21EA", + careof: "2105", + caron: "02C7", + caronbelowcmb: "032C", + caroncmb: "030C", + carriagereturn: "21B5", + cbopomofo: "3118", + ccaron: "010D", + ccedilla: "00E7", + ccedillaacute: "1E09", + ccircle: "24D2", + ccircumflex: "0109", + ccurl: "0255", + cdot: "010B", + cdotaccent: "010B", + cdsquare: "33C5", + cedilla: "00B8", + cedillacmb: "0327", + cent: "00A2", + centigrade: "2103", + centinferior: "F6DF", + centmonospace: "FFE0", + centoldstyle: "F7A2", + centsuperior: "F6E0", + chaarmenian: "0579", + chabengali: "099B", + chadeva: "091B", + chagujarati: "0A9B", + chagurmukhi: "0A1B", + chbopomofo: "3114", + cheabkhasiancyrillic: "04BD", + checkmark: "2713", + checyrillic: "0447", + chedescenderabkhasiancyrillic: "04BF", + chedescendercyrillic: "04B7", + chedieresiscyrillic: "04F5", + cheharmenian: "0573", + chekhakassiancyrillic: "04CC", + cheverticalstrokecyrillic: "04B9", + chi: "03C7", + chieuchacirclekorean: "3277", + chieuchaparenkorean: "3217", + chieuchcirclekorean: "3269", + chieuchkorean: "314A", + chieuchparenkorean: "3209", + chochangthai: "0E0A", + chochanthai: "0E08", + chochingthai: "0E09", + chochoethai: "0E0C", + chook: "0188", + cieucacirclekorean: "3276", + cieucaparenkorean: "3216", + cieuccirclekorean: "3268", + cieuckorean: "3148", + cieucparenkorean: "3208", + cieucuparenkorean: "321C", + circle: "25CB", + circlemultiply: "2297", + circleot: "2299", + circleplus: "2295", + circlepostalmark: "3036", + circlewithlefthalfblack: "25D0", + circlewithrighthalfblack: "25D1", + circumflex: "02C6", + circumflexbelowcmb: "032D", + circumflexcmb: "0302", + clear: "2327", + clickalveolar: "01C2", + clickdental: "01C0", + clicklateral: "01C1", + clickretroflex: "01C3", + club: "2663", + clubsuitblack: "2663", + clubsuitwhite: "2667", + cmcubedsquare: "33A4", + cmonospace: "FF43", + cmsquaredsquare: "33A0", + coarmenian: "0581", + colon: "003A", + colonmonetary: "20A1", + colonmonospace: "FF1A", + colonsign: "20A1", + colonsmall: "FE55", + colontriangularhalfmod: "02D1", + colontriangularmod: "02D0", + comma: "002C", + commaabovecmb: "0313", + commaaboverightcmb: "0315", + commaaccent: "F6C3", + commaarabic: "060C", + commaarmenian: "055D", + commainferior: "F6E1", + commamonospace: "FF0C", + commareversedabovecmb: "0314", + commareversedmod: "02BD", + commasmall: "FE50", + commasuperior: "F6E2", + commaturnedabovecmb: "0312", + commaturnedmod: "02BB", + compass: "263C", + congruent: "2245", + contourintegral: "222E", + control: "2303", + controlACK: "0006", + controlBEL: "0007", + controlBS: "0008", + controlCAN: "0018", + controlCR: "000D", + controlDC1: "0011", + controlDC2: "0012", + controlDC3: "0013", + controlDC4: "0014", + controlDEL: "007F", + controlDLE: "0010", + controlEM: "0019", + controlENQ: "0005", + controlEOT: "0004", + controlESC: "001B", + controlETB: "0017", + controlETX: "0003", + controlFF: "000C", + controlFS: "001C", + controlGS: "001D", + controlHT: "0009", + controlLF: "000A", + controlNAK: "0015", + controlRS: "001E", + controlSI: "000F", + controlSO: "000E", + controlSOT: "0002", + controlSTX: "0001", + controlSUB: "001A", + controlSYN: "0016", + controlUS: "001F", + controlVT: "000B", + copyright: "00A9", + copyrightsans: "F8E9", + copyrightserif: "F6D9", + cornerbracketleft: "300C", + cornerbracketlefthalfwidth: "FF62", + cornerbracketleftvertical: "FE41", + cornerbracketright: "300D", + cornerbracketrighthalfwidth: "FF63", + cornerbracketrightvertical: "FE42", + corporationsquare: "337F", + cosquare: "33C7", + coverkgsquare: "33C6", + cparen: "249E", + cruzeiro: "20A2", + cstretched: "0297", + curlyand: "22CF", + curlyor: "22CE", + currency: "00A4", + cyrBreve: "F6D1", + cyrFlex: "F6D2", + cyrbreve: "F6D4", + cyrflex: "F6D5", + d: "0064", + daarmenian: "0564", + dabengali: "09A6", + dadarabic: "0636", + dadeva: "0926", + dadfinalarabic: "FEBE", + dadinitialarabic: "FEBF", + dadmedialarabic: "FEC0", + dagesh: "05BC", + dageshhebrew: "05BC", + dagger: "2020", + daggerdbl: "2021", + dagujarati: "0AA6", + dagurmukhi: "0A26", + dahiragana: "3060", + dakatakana: "30C0", + dalarabic: "062F", + dalet: "05D3", + daletdagesh: "FB33", + daletdageshhebrew: "FB33", dalethatafpatah: "05D3 05B2", dalethatafpatahhebrew: "05D3 05B2", dalethatafsegol: "05D3 05B1", dalethatafsegolhebrew: "05D3 05B1", - dalethebrew: 0x05D3, + dalethebrew: "05D3", dalethiriq: "05D3 05B4", dalethiriqhebrew: "05D3 05B4", daletholam: "05D3 05B9", @@ -1521,1641 +1521,1641 @@ var GlyphsUnicode = { 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, + dalfinalarabic: "FEAA", + dammaarabic: "064F", + dammalowarabic: "064F", + dammatanaltonearabic: "064C", + dammatanarabic: "064C", + danda: "0964", + dargahebrew: "05A7", + dargalefthebrew: "05A7", + dasiapneumatacyrilliccmb: "0485", + dblGrave: "F6D3", + dblanglebracketleft: "300A", + dblanglebracketleftvertical: "FE3D", + dblanglebracketright: "300B", + dblanglebracketrightvertical: "FE3E", + dblarchinvertedbelowcmb: "032B", + dblarrowleft: "21D4", + dblarrowright: "21D2", + dbldanda: "0965", + dblgrave: "F6D6", + dblgravecmb: "030F", + dblintegral: "222C", + dbllowline: "2017", + dbllowlinecmb: "0333", + dbloverlinecmb: "033F", + dblprimemod: "02BA", + dblverticalbar: "2016", + dblverticallineabovecmb: "030E", + dbopomofo: "3109", + dbsquare: "33C8", + dcaron: "010F", + dcedilla: "1E11", + dcircle: "24D3", + dcircumflexbelow: "1E13", + dcroat: "0111", + ddabengali: "09A1", + ddadeva: "0921", + ddagujarati: "0AA1", + ddagurmukhi: "0A21", + ddalarabic: "0688", + ddalfinalarabic: "FB89", + dddhadeva: "095C", + ddhabengali: "09A2", + ddhadeva: "0922", + ddhagujarati: "0AA2", + ddhagurmukhi: "0A22", + ddotaccent: "1E0B", + ddotbelow: "1E0D", + decimalseparatorarabic: "066B", + decimalseparatorpersian: "066B", + decyrillic: "0434", + degree: "00B0", + dehihebrew: "05AD", + dehiragana: "3067", + deicoptic: "03EF", + dekatakana: "30C7", + deleteleft: "232B", + deleteright: "2326", + delta: "03B4", + deltaturned: "018D", + denominatorminusonenumeratorbengali: "09F8", + dezh: "02A4", + dhabengali: "09A7", + dhadeva: "0927", + dhagujarati: "0AA7", + dhagurmukhi: "0A27", + dhook: "0257", + dialytikatonos: "0385", + dialytikatonoscmb: "0344", + diamond: "2666", + diamondsuitwhite: "2662", + dieresis: "00A8", + dieresisacute: "F6D7", + dieresisbelowcmb: "0324", + dieresiscmb: "0308", + dieresisgrave: "F6D8", + dieresistonos: "0385", + dihiragana: "3062", + dikatakana: "30C2", + dittomark: "3003", + divide: "00F7", + divides: "2223", + divisionslash: "2215", + djecyrillic: "0452", + dkshade: "2593", + dlinebelow: "1E0F", + dlsquare: "3397", + dmacron: "0111", + dmonospace: "FF44", + dnblock: "2584", + dochadathai: "0E0E", + dodekthai: "0E14", + dohiragana: "3069", + dokatakana: "30C9", + dollar: "0024", + dollarinferior: "F6E3", + dollarmonospace: "FF04", + dollaroldstyle: "F724", + dollarsmall: "FE69", + dollarsuperior: "F6E4", + dong: "20AB", + dorusquare: "3326", + dotaccent: "02D9", + dotaccentcmb: "0307", + dotbelowcmb: "0323", + dotbelowcomb: "0323", + dotkatakana: "30FB", + dotlessi: "0131", + dotlessj: "F6BE", + dotlessjstrokehook: "0284", + dotmath: "22C5", + dottedcircle: "25CC", + doubleyodpatah: "FB1F", + doubleyodpatahhebrew: "FB1F", + downtackbelowcmb: "031E", + downtackmod: "02D5", + dparen: "249F", + dsuperior: "F6EB", + dtail: "0256", + dtopbar: "018C", + duhiragana: "3065", + dukatakana: "30C5", + dz: "01F3", + dzaltone: "02A3", + dzcaron: "01C6", + dzcurl: "02A5", + dzeabkhasiancyrillic: "04E1", + dzecyrillic: "0455", + dzhecyrillic: "045F", + e: "0065", + eacute: "00E9", + earth: "2641", + ebengali: "098F", + ebopomofo: "311C", + ebreve: "0115", + ecandradeva: "090D", + ecandragujarati: "0A8D", + ecandravowelsigndeva: "0945", + ecandravowelsigngujarati: "0AC5", + ecaron: "011B", + ecedillabreve: "1E1D", + echarmenian: "0565", + echyiwnarmenian: "0587", + ecircle: "24D4", + ecircumflex: "00EA", + ecircumflexacute: "1EBF", + ecircumflexbelow: "1E19", + ecircumflexdotbelow: "1EC7", + ecircumflexgrave: "1EC1", + ecircumflexhookabove: "1EC3", + ecircumflextilde: "1EC5", + ecyrillic: "0454", + edblgrave: "0205", + edeva: "090F", + edieresis: "00EB", + edot: "0117", + edotaccent: "0117", + edotbelow: "1EB9", + eegurmukhi: "0A0F", + eematragurmukhi: "0A47", + efcyrillic: "0444", + egrave: "00E8", + egujarati: "0A8F", + eharmenian: "0567", + ehbopomofo: "311D", + ehiragana: "3048", + ehookabove: "1EBB", + eibopomofo: "311F", + eight: "0038", + eightarabic: "0668", + eightbengali: "09EE", + eightcircle: "2467", + eightcircleinversesansserif: "2791", + eightdeva: "096E", + eighteencircle: "2471", + eighteenparen: "2485", + eighteenperiod: "2499", + eightgujarati: "0AEE", + eightgurmukhi: "0A6E", + eighthackarabic: "0668", + eighthangzhou: "3028", + eighthnotebeamed: "266B", + eightideographicparen: "3227", + eightinferior: "2088", + eightmonospace: "FF18", + eightoldstyle: "F738", + eightparen: "247B", + eightperiod: "248F", + eightpersian: "06F8", + eightroman: "2177", + eightsuperior: "2078", + eightthai: "0E58", + einvertedbreve: "0207", + eiotifiedcyrillic: "0465", + ekatakana: "30A8", + ekatakanahalfwidth: "FF74", + ekonkargurmukhi: "0A74", + ekorean: "3154", + elcyrillic: "043B", + element: "2208", + elevencircle: "246A", + elevenparen: "247E", + elevenperiod: "2492", + elevenroman: "217A", + ellipsis: "2026", + ellipsisvertical: "22EE", + emacron: "0113", + emacronacute: "1E17", + emacrongrave: "1E15", + emcyrillic: "043C", + emdash: "2014", + emdashvertical: "FE31", + emonospace: "FF45", + emphasismarkarmenian: "055B", + emptyset: "2205", + enbopomofo: "3123", + encyrillic: "043D", + endash: "2013", + endashvertical: "FE32", + endescendercyrillic: "04A3", + eng: "014B", + engbopomofo: "3125", + enghecyrillic: "04A5", + enhookcyrillic: "04C8", + enspace: "2002", + eogonek: "0119", + eokorean: "3153", + eopen: "025B", + eopenclosed: "029A", + eopenreversed: "025C", + eopenreversedclosed: "025E", + eopenreversedhook: "025D", + eparen: "24A0", + epsilon: "03B5", + epsilontonos: "03AD", + equal: "003D", + equalmonospace: "FF1D", + equalsmall: "FE66", + equalsuperior: "207C", + equivalence: "2261", + erbopomofo: "3126", + ercyrillic: "0440", + ereversed: "0258", + ereversedcyrillic: "044D", + escyrillic: "0441", + esdescendercyrillic: "04AB", + esh: "0283", + eshcurl: "0286", + eshortdeva: "090E", + eshortvowelsigndeva: "0946", + eshreversedloop: "01AA", + eshsquatreversed: "0285", + esmallhiragana: "3047", + esmallkatakana: "30A7", + esmallkatakanahalfwidth: "FF6A", + estimated: "212E", + esuperior: "F6EC", + eta: "03B7", + etarmenian: "0568", + etatonos: "03AE", + eth: "00F0", + etilde: "1EBD", + etildebelow: "1E1B", + etnahtafoukhhebrew: "0591", + etnahtafoukhlefthebrew: "0591", + etnahtahebrew: "0591", + etnahtalefthebrew: "0591", + eturned: "01DD", + eukorean: "3161", + euro: "20AC", + evowelsignbengali: "09C7", + evowelsigndeva: "0947", + evowelsigngujarati: "0AC7", + exclam: "0021", + exclamarmenian: "055C", + exclamdbl: "203C", + exclamdown: "00A1", + exclamdownsmall: "F7A1", + exclammonospace: "FF01", + exclamsmall: "F721", + existential: "2203", + ezh: "0292", + ezhcaron: "01EF", + ezhcurl: "0293", + ezhreversed: "01B9", + ezhtail: "01BA", + f: "0066", + fadeva: "095E", + fagurmukhi: "0A5E", + fahrenheit: "2109", + fathaarabic: "064E", + fathalowarabic: "064E", + fathatanarabic: "064B", + fbopomofo: "3108", + fcircle: "24D5", + fdotaccent: "1E1F", + feharabic: "0641", + feharmenian: "0586", + fehfinalarabic: "FED2", + fehinitialarabic: "FED3", + fehmedialarabic: "FED4", + feicoptic: "03E5", + female: "2640", + ff: "FB00", + ffi: "FB03", + ffl: "FB04", + fi: "FB01", + fifteencircle: "246E", + fifteenparen: "2482", + fifteenperiod: "2496", + figuredash: "2012", + filledbox: "25A0", + filledrect: "25AC", + finalkaf: "05DA", + finalkafdagesh: "FB3A", + finalkafdageshhebrew: "FB3A", + finalkafhebrew: "05DA", 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, + finalmem: "05DD", + finalmemhebrew: "05DD", + finalnun: "05DF", + finalnunhebrew: "05DF", + finalpe: "05E3", + finalpehebrew: "05E3", + finaltsadi: "05E5", + finaltsadihebrew: "05E5", + firsttonechinese: "02C9", + fisheye: "25C9", + fitacyrillic: "0473", + five: "0035", + fivearabic: "0665", + fivebengali: "09EB", + fivecircle: "2464", + fivecircleinversesansserif: "278E", + fivedeva: "096B", + fiveeighths: "215D", + fivegujarati: "0AEB", + fivegurmukhi: "0A6B", + fivehackarabic: "0665", + fivehangzhou: "3025", + fiveideographicparen: "3224", + fiveinferior: "2085", + fivemonospace: "FF15", + fiveoldstyle: "F735", + fiveparen: "2478", + fiveperiod: "248C", + fivepersian: "06F5", + fiveroman: "2174", + fivesuperior: "2075", + fivethai: "0E55", + fl: "FB02", + florin: "0192", + fmonospace: "FF46", + fmsquare: "3399", + fofanthai: "0E1F", + fofathai: "0E1D", + fongmanthai: "0E4F", + forall: "2200", + four: "0034", + fourarabic: "0664", + fourbengali: "09EA", + fourcircle: "2463", + fourcircleinversesansserif: "278D", + fourdeva: "096A", + fourgujarati: "0AEA", + fourgurmukhi: "0A6A", + fourhackarabic: "0664", + fourhangzhou: "3024", + fourideographicparen: "3223", + fourinferior: "2084", + fourmonospace: "FF14", + fournumeratorbengali: "09F7", + fouroldstyle: "F734", + fourparen: "2477", + fourperiod: "248B", + fourpersian: "06F4", + fourroman: "2173", + foursuperior: "2074", + fourteencircle: "246D", + fourteenparen: "2481", + fourteenperiod: "2495", + fourthai: "0E54", + fourthtonechinese: "02CB", + fparen: "24A1", + fraction: "2044", + franc: "20A3", + g: "0067", + gabengali: "0997", + gacute: "01F5", + gadeva: "0917", + gafarabic: "06AF", + gaffinalarabic: "FB93", + gafinitialarabic: "FB94", + gafmedialarabic: "FB95", + gagujarati: "0A97", + gagurmukhi: "0A17", + gahiragana: "304C", + gakatakana: "30AC", + gamma: "03B3", + gammalatinsmall: "0263", + gammasuperior: "02E0", + gangiacoptic: "03EB", + gbopomofo: "310D", + gbreve: "011F", + gcaron: "01E7", + gcedilla: "0123", + gcircle: "24D6", + gcircumflex: "011D", + gcommaaccent: "0123", + gdot: "0121", + gdotaccent: "0121", + gecyrillic: "0433", + gehiragana: "3052", + gekatakana: "30B2", + geometricallyequal: "2251", + gereshaccenthebrew: "059C", + gereshhebrew: "05F3", + gereshmuqdamhebrew: "059D", + germandbls: "00DF", + gershayimaccenthebrew: "059E", + gershayimhebrew: "05F4", + getamark: "3013", + ghabengali: "0998", + ghadarmenian: "0572", + ghadeva: "0918", + ghagujarati: "0A98", + ghagurmukhi: "0A18", + ghainarabic: "063A", + ghainfinalarabic: "FECE", + ghaininitialarabic: "FECF", + ghainmedialarabic: "FED0", + ghemiddlehookcyrillic: "0495", + ghestrokecyrillic: "0493", + gheupturncyrillic: "0491", + ghhadeva: "095A", + ghhagurmukhi: "0A5A", + ghook: "0260", + ghzsquare: "3393", + gihiragana: "304E", + gikatakana: "30AE", + gimarmenian: "0563", + gimel: "05D2", + gimeldagesh: "FB32", + gimeldageshhebrew: "FB32", + gimelhebrew: "05D2", + gjecyrillic: "0453", + glottalinvertedstroke: "01BE", + glottalstop: "0294", + glottalstopinverted: "0296", + glottalstopmod: "02C0", + glottalstopreversed: "0295", + glottalstopreversedmod: "02C1", + glottalstopreversedsuperior: "02E4", + glottalstopstroke: "02A1", + glottalstopstrokereversed: "02A2", + gmacron: "1E21", + gmonospace: "FF47", + gohiragana: "3054", + gokatakana: "30B4", + gparen: "24A2", + gpasquare: "33AC", + gradient: "2207", + grave: "0060", + gravebelowcmb: "0316", + gravecmb: "0300", + gravecomb: "0300", + gravedeva: "0953", + gravelowmod: "02CE", + gravemonospace: "FF40", + gravetonecmb: "0340", + greater: "003E", + greaterequal: "2265", + greaterequalorless: "22DB", + greatermonospace: "FF1E", + greaterorequivalent: "2273", + greaterorless: "2277", + greateroverequal: "2267", + greatersmall: "FE65", + gscript: "0261", + gstroke: "01E5", + guhiragana: "3050", + guillemotleft: "00AB", + guillemotright: "00BB", + guilsinglleft: "2039", + guilsinglright: "203A", + gukatakana: "30B0", + guramusquare: "3318", + gysquare: "33C9", + h: "0068", + haabkhasiancyrillic: "04A9", + haaltonearabic: "06C1", + habengali: "09B9", + hadescendercyrillic: "04B3", + hadeva: "0939", + hagujarati: "0AB9", + hagurmukhi: "0A39", + haharabic: "062D", + hahfinalarabic: "FEA2", + hahinitialarabic: "FEA3", + hahiragana: "306F", + hahmedialarabic: "FEA4", + haitusquare: "332A", + hakatakana: "30CF", + hakatakanahalfwidth: "FF8A", + halantgurmukhi: "0A4D", + hamzaarabic: "0621", hamzadammaarabic: "0621 064F", hamzadammatanarabic: "0621 064C", hamzafathaarabic: "0621 064E", hamzafathatanarabic: "0621 064B", - hamzalowarabic: 0x0621, + hamzalowarabic: "0621", 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, + hangulfiller: "3164", + hardsigncyrillic: "044A", + harpoonleftbarbup: "21BC", + harpoonrightbarbup: "21C0", + hasquare: "33CA", + hatafpatah: "05B2", + hatafpatah16: "05B2", + hatafpatah23: "05B2", + hatafpatah2f: "05B2", + hatafpatahhebrew: "05B2", + hatafpatahnarrowhebrew: "05B2", + hatafpatahquarterhebrew: "05B2", + hatafpatahwidehebrew: "05B2", + hatafqamats: "05B3", + hatafqamats1b: "05B3", + hatafqamats28: "05B3", + hatafqamats34: "05B3", + hatafqamatshebrew: "05B3", + hatafqamatsnarrowhebrew: "05B3", + hatafqamatsquarterhebrew: "05B3", + hatafqamatswidehebrew: "05B3", + hatafsegol: "05B1", + hatafsegol17: "05B1", + hatafsegol24: "05B1", + hatafsegol30: "05B1", + hatafsegolhebrew: "05B1", + hatafsegolnarrowhebrew: "05B1", + hatafsegolquarterhebrew: "05B1", + hatafsegolwidehebrew: "05B1", + hbar: "0127", + hbopomofo: "310F", + hbrevebelow: "1E2B", + hcedilla: "1E29", + hcircle: "24D7", + hcircumflex: "0125", + hdieresis: "1E27", + hdotaccent: "1E23", + hdotbelow: "1E25", + he: "05D4", + heart: "2665", + heartsuitblack: "2665", + heartsuitwhite: "2661", + hedagesh: "FB34", + hedageshhebrew: "FB34", + hehaltonearabic: "06C1", + heharabic: "0647", + hehebrew: "05D4", + hehfinalaltonearabic: "FBA7", + hehfinalalttwoarabic: "FEEA", + hehfinalarabic: "FEEA", + hehhamzaabovefinalarabic: "FBA5", + hehhamzaaboveisolatedarabic: "FBA4", + hehinitialaltonearabic: "FBA8", + hehinitialarabic: "FEEB", + hehiragana: "3078", + hehmedialaltonearabic: "FBA9", + hehmedialarabic: "FEEC", + heiseierasquare: "337B", + hekatakana: "30D8", + hekatakanahalfwidth: "FF8D", + hekutaarusquare: "3336", + henghook: "0267", + herutusquare: "3339", + het: "05D7", + hethebrew: "05D7", + hhook: "0266", + hhooksuperior: "02B1", + hieuhacirclekorean: "327B", + hieuhaparenkorean: "321B", + hieuhcirclekorean: "326D", + hieuhkorean: "314E", + hieuhparenkorean: "320D", + hihiragana: "3072", + hikatakana: "30D2", + hikatakanahalfwidth: "FF8B", + hiriq: "05B4", + hiriq14: "05B4", + hiriq21: "05B4", + hiriq2d: "05B4", + hiriqhebrew: "05B4", + hiriqnarrowhebrew: "05B4", + hiriqquarterhebrew: "05B4", + hiriqwidehebrew: "05B4", + hlinebelow: "1E96", + hmonospace: "FF48", + hoarmenian: "0570", + hohipthai: "0E2B", + hohiragana: "307B", + hokatakana: "30DB", + hokatakanahalfwidth: "FF8E", + holam: "05B9", + holam19: "05B9", + holam26: "05B9", + holam32: "05B9", + holamhebrew: "05B9", + holamnarrowhebrew: "05B9", + holamquarterhebrew: "05B9", + holamwidehebrew: "05B9", + honokhukthai: "0E2E", + hookabovecomb: "0309", + hookcmb: "0309", + hookpalatalizedbelowcmb: "0321", + hookretroflexbelowcmb: "0322", + hoonsquare: "3342", + horicoptic: "03E9", + horizontalbar: "2015", + horncmb: "031B", + hotsprings: "2668", + house: "2302", + hparen: "24A3", + hsuperior: "02B0", + hturned: "0265", + huhiragana: "3075", + huiitosquare: "3333", + hukatakana: "30D5", + hukatakanahalfwidth: "FF8C", + hungarumlaut: "02DD", + hungarumlautcmb: "030B", + hv: "0195", + hyphen: "002D", + hypheninferior: "F6E5", + hyphenmonospace: "FF0D", + hyphensmall: "FE63", + hyphensuperior: "F6E6", + hyphentwo: "2010", + i: "0069", + iacute: "00ED", + iacyrillic: "044F", + ibengali: "0987", + ibopomofo: "3127", + ibreve: "012D", + icaron: "01D0", + icircle: "24D8", + icircumflex: "00EE", + icyrillic: "0456", + idblgrave: "0209", + ideographearthcircle: "328F", + ideographfirecircle: "328B", + ideographicallianceparen: "323F", + ideographiccallparen: "323A", + ideographiccentrecircle: "32A5", + ideographicclose: "3006", + ideographiccomma: "3001", + ideographiccommaleft: "FF64", + ideographiccongratulationparen: "3237", + ideographiccorrectcircle: "32A3", + ideographicearthparen: "322F", + ideographicenterpriseparen: "323D", + ideographicexcellentcircle: "329D", + ideographicfestivalparen: "3240", + ideographicfinancialcircle: "3296", + ideographicfinancialparen: "3236", + ideographicfireparen: "322B", + ideographichaveparen: "3232", + ideographichighcircle: "32A4", + ideographiciterationmark: "3005", + ideographiclaborcircle: "3298", + ideographiclaborparen: "3238", + ideographicleftcircle: "32A7", + ideographiclowcircle: "32A6", + ideographicmedicinecircle: "32A9", + ideographicmetalparen: "322E", + ideographicmoonparen: "322A", + ideographicnameparen: "3234", + ideographicperiod: "3002", + ideographicprintcircle: "329E", + ideographicreachparen: "3243", + ideographicrepresentparen: "3239", + ideographicresourceparen: "323E", + ideographicrightcircle: "32A8", + ideographicsecretcircle: "3299", + ideographicselfparen: "3242", + ideographicsocietyparen: "3233", + ideographicspace: "3000", + ideographicspecialparen: "3235", + ideographicstockparen: "3231", + ideographicstudyparen: "323B", + ideographicsunparen: "3230", + ideographicsuperviseparen: "323C", + ideographicwaterparen: "322C", + ideographicwoodparen: "322D", + ideographiczero: "3007", + ideographmetalcircle: "328E", + ideographmooncircle: "328A", + ideographnamecircle: "3294", + ideographsuncircle: "3290", + ideographwatercircle: "328C", + ideographwoodcircle: "328D", + ideva: "0907", + idieresis: "00EF", + idieresisacute: "1E2F", + idieresiscyrillic: "04E5", + idotbelow: "1ECB", + iebrevecyrillic: "04D7", + iecyrillic: "0435", + ieungacirclekorean: "3275", + ieungaparenkorean: "3215", + ieungcirclekorean: "3267", + ieungkorean: "3147", + ieungparenkorean: "3207", + igrave: "00EC", + igujarati: "0A87", + igurmukhi: "0A07", + ihiragana: "3044", + ihookabove: "1EC9", + iibengali: "0988", + iicyrillic: "0438", + iideva: "0908", + iigujarati: "0A88", + iigurmukhi: "0A08", + iimatragurmukhi: "0A40", + iinvertedbreve: "020B", + iishortcyrillic: "0439", + iivowelsignbengali: "09C0", + iivowelsigndeva: "0940", + iivowelsigngujarati: "0AC0", + ij: "0133", + ikatakana: "30A4", + ikatakanahalfwidth: "FF72", + ikorean: "3163", + ilde: "02DC", + iluyhebrew: "05AC", + imacron: "012B", + imacroncyrillic: "04E3", + imageorapproximatelyequal: "2253", + imatragurmukhi: "0A3F", + imonospace: "FF49", + increment: "2206", + infinity: "221E", + iniarmenian: "056B", + integral: "222B", + integralbottom: "2321", + integralbt: "2321", + integralex: "F8F5", + integraltop: "2320", + integraltp: "2320", + intersection: "2229", + intisquare: "3305", + invbullet: "25D8", + invcircle: "25D9", + invsmileface: "263B", + iocyrillic: "0451", + iogonek: "012F", + iota: "03B9", + iotadieresis: "03CA", + iotadieresistonos: "0390", + iotalatin: "0269", + iotatonos: "03AF", + iparen: "24A4", + irigurmukhi: "0A72", + ismallhiragana: "3043", + ismallkatakana: "30A3", + ismallkatakanahalfwidth: "FF68", + issharbengali: "09FA", + istroke: "0268", + isuperior: "F6ED", + iterationhiragana: "309D", + iterationkatakana: "30FD", + itilde: "0129", + itildebelow: "1E2D", + iubopomofo: "3129", + iucyrillic: "044E", + ivowelsignbengali: "09BF", + ivowelsigndeva: "093F", + ivowelsigngujarati: "0ABF", + izhitsacyrillic: "0475", + izhitsadblgravecyrillic: "0477", + j: "006A", + jaarmenian: "0571", + jabengali: "099C", + jadeva: "091C", + jagujarati: "0A9C", + jagurmukhi: "0A1C", + jbopomofo: "3110", + jcaron: "01F0", + jcircle: "24D9", + jcircumflex: "0135", + jcrossedtail: "029D", + jdotlessstroke: "025F", + jecyrillic: "0458", + jeemarabic: "062C", + jeemfinalarabic: "FE9E", + jeeminitialarabic: "FE9F", + jeemmedialarabic: "FEA0", + jeharabic: "0698", + jehfinalarabic: "FB8B", + jhabengali: "099D", + jhadeva: "091D", + jhagujarati: "0A9D", + jhagurmukhi: "0A1D", + jheharmenian: "057B", + jis: "3004", + jmonospace: "FF4A", + jparen: "24A5", + jsuperior: "02B2", + k: "006B", + kabashkircyrillic: "04A1", + kabengali: "0995", + kacute: "1E31", + kacyrillic: "043A", + kadescendercyrillic: "049B", + kadeva: "0915", + kaf: "05DB", + kafarabic: "0643", + kafdagesh: "FB3B", + kafdageshhebrew: "FB3B", + kaffinalarabic: "FEDA", + kafhebrew: "05DB", + kafinitialarabic: "FEDB", + kafmedialarabic: "FEDC", + kafrafehebrew: "FB4D", + kagujarati: "0A95", + kagurmukhi: "0A15", + kahiragana: "304B", + kahookcyrillic: "04C4", + kakatakana: "30AB", + kakatakanahalfwidth: "FF76", + kappa: "03BA", + kappasymbolgreek: "03F0", + kapyeounmieumkorean: "3171", + kapyeounphieuphkorean: "3184", + kapyeounpieupkorean: "3178", + kapyeounssangpieupkorean: "3179", + karoriisquare: "330D", + kashidaautoarabic: "0640", + kashidaautonosidebearingarabic: "0640", + kasmallkatakana: "30F5", + kasquare: "3384", + kasraarabic: "0650", + kasratanarabic: "064D", + kastrokecyrillic: "049F", + katahiraprolongmarkhalfwidth: "FF70", + kaverticalstrokecyrillic: "049D", + kbopomofo: "310E", + kcalsquare: "3389", + kcaron: "01E9", + kcedilla: "0137", + kcircle: "24DA", + kcommaaccent: "0137", + kdotbelow: "1E33", + keharmenian: "0584", + kehiragana: "3051", + kekatakana: "30B1", + kekatakanahalfwidth: "FF79", + kenarmenian: "056F", + kesmallkatakana: "30F6", + kgreenlandic: "0138", + khabengali: "0996", + khacyrillic: "0445", + khadeva: "0916", + khagujarati: "0A96", + khagurmukhi: "0A16", + khaharabic: "062E", + khahfinalarabic: "FEA6", + khahinitialarabic: "FEA7", + khahmedialarabic: "FEA8", + kheicoptic: "03E7", + khhadeva: "0959", + khhagurmukhi: "0A59", + khieukhacirclekorean: "3278", + khieukhaparenkorean: "3218", + khieukhcirclekorean: "326A", + khieukhkorean: "314B", + khieukhparenkorean: "320A", + khokhaithai: "0E02", + khokhonthai: "0E05", + khokhuatthai: "0E03", + khokhwaithai: "0E04", + khomutthai: "0E5B", + khook: "0199", + khorakhangthai: "0E06", + khzsquare: "3391", + kihiragana: "304D", + kikatakana: "30AD", + kikatakanahalfwidth: "FF77", + kiroguramusquare: "3315", + kiromeetorusquare: "3316", + kirosquare: "3314", + kiyeokacirclekorean: "326E", + kiyeokaparenkorean: "320E", + kiyeokcirclekorean: "3260", + kiyeokkorean: "3131", + kiyeokparenkorean: "3200", + kiyeoksioskorean: "3133", + kjecyrillic: "045C", + klinebelow: "1E35", + klsquare: "3398", + kmcubedsquare: "33A6", + kmonospace: "FF4B", + kmsquaredsquare: "33A2", + kohiragana: "3053", + kohmsquare: "33C0", + kokaithai: "0E01", + kokatakana: "30B3", + kokatakanahalfwidth: "FF7A", + kooposquare: "331E", + koppacyrillic: "0481", + koreanstandardsymbol: "327F", + koroniscmb: "0343", + kparen: "24A6", + kpasquare: "33AA", + ksicyrillic: "046F", + ktsquare: "33CF", + kturned: "029E", + kuhiragana: "304F", + kukatakana: "30AF", + kukatakanahalfwidth: "FF78", + kvsquare: "33B8", + kwsquare: "33BE", + l: "006C", + labengali: "09B2", + lacute: "013A", + ladeva: "0932", + lagujarati: "0AB2", + lagurmukhi: "0A32", + lakkhangyaothai: "0E45", + lamaleffinalarabic: "FEFC", + lamalefhamzaabovefinalarabic: "FEF8", + lamalefhamzaaboveisolatedarabic: "FEF7", + lamalefhamzabelowfinalarabic: "FEFA", + lamalefhamzabelowisolatedarabic: "FEF9", + lamalefisolatedarabic: "FEFB", + lamalefmaddaabovefinalarabic: "FEF6", + lamalefmaddaaboveisolatedarabic: "FEF5", + lamarabic: "0644", + lambda: "03BB", + lambdastroke: "019B", + lamed: "05DC", + lameddagesh: "FB3C", + lameddageshhebrew: "FB3C", + lamedhebrew: "05DC", 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, + lamfinalarabic: "FEDE", + lamhahinitialarabic: "FCCA", + laminitialarabic: "FEDF", + lamjeeminitialarabic: "FCC9", + lamkhahinitialarabic: "FCCB", + lamlamhehisolatedarabic: "FDF2", + lammedialarabic: "FEE0", + lammeemhahinitialarabic: "FD88", + lammeeminitialarabic: "FCCC", 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, + largecircle: "25EF", + lbar: "019A", + lbelt: "026C", + lbopomofo: "310C", + lcaron: "013E", + lcedilla: "013C", + lcircle: "24DB", + lcircumflexbelow: "1E3D", + lcommaaccent: "013C", + ldot: "0140", + ldotaccent: "0140", + ldotbelow: "1E37", + ldotbelowmacron: "1E39", + leftangleabovecmb: "031A", + lefttackbelowcmb: "0318", + less: "003C", + lessequal: "2264", + lessequalorgreater: "22DA", + lessmonospace: "FF1C", + lessorequivalent: "2272", + lessorgreater: "2276", + lessoverequal: "2266", + lesssmall: "FE64", + lezh: "026E", + lfblock: "258C", + lhookretroflex: "026D", + lira: "20A4", + liwnarmenian: "056C", + lj: "01C9", + ljecyrillic: "0459", + ll: "F6C0", + lladeva: "0933", + llagujarati: "0AB3", + llinebelow: "1E3B", + llladeva: "0934", + llvocalicbengali: "09E1", + llvocalicdeva: "0961", + llvocalicvowelsignbengali: "09E3", + llvocalicvowelsigndeva: "0963", + lmiddletilde: "026B", + lmonospace: "FF4C", + lmsquare: "33D0", + lochulathai: "0E2C", + logicaland: "2227", + logicalnot: "00AC", + logicalnotreversed: "2310", + logicalor: "2228", + lolingthai: "0E25", + longs: "017F", + lowlinecenterline: "FE4E", + lowlinecmb: "0332", + lowlinedashed: "FE4D", + lozenge: "25CA", + lparen: "24A7", + lslash: "0142", + lsquare: "2113", + lsuperior: "F6EE", + ltshade: "2591", + luthai: "0E26", + lvocalicbengali: "098C", + lvocalicdeva: "090C", + lvocalicvowelsignbengali: "09E2", + lvocalicvowelsigndeva: "0962", + lxsquare: "33D3", + m: "006D", + mabengali: "09AE", + macron: "00AF", + macronbelowcmb: "0331", + macroncmb: "0304", + macronlowmod: "02CD", + macronmonospace: "FFE3", + macute: "1E3F", + madeva: "092E", + magujarati: "0AAE", + magurmukhi: "0A2E", + mahapakhhebrew: "05A4", + mahapakhlefthebrew: "05A4", + mahiragana: "307E", + maichattawalowleftthai: "F895", + maichattawalowrightthai: "F894", + maichattawathai: "0E4B", + maichattawaupperleftthai: "F893", + maieklowleftthai: "F88C", + maieklowrightthai: "F88B", + maiekthai: "0E48", + maiekupperleftthai: "F88A", + maihanakatleftthai: "F884", + maihanakatthai: "0E31", + maitaikhuleftthai: "F889", + maitaikhuthai: "0E47", + maitholowleftthai: "F88F", + maitholowrightthai: "F88E", + maithothai: "0E49", + maithoupperleftthai: "F88D", + maitrilowleftthai: "F892", + maitrilowrightthai: "F891", + maitrithai: "0E4A", + maitriupperleftthai: "F890", + maiyamokthai: "0E46", + makatakana: "30DE", + makatakanahalfwidth: "FF8F", + male: "2642", + mansyonsquare: "3347", + maqafhebrew: "05BE", + mars: "2642", + masoracirclehebrew: "05AF", + masquare: "3383", + mbopomofo: "3107", + mbsquare: "33D4", + mcircle: "24DC", + mcubedsquare: "33A5", + mdotaccent: "1E41", + mdotbelow: "1E43", + meemarabic: "0645", + meemfinalarabic: "FEE2", + meeminitialarabic: "FEE3", + meemmedialarabic: "FEE4", + meemmeeminitialarabic: "FCD1", + meemmeemisolatedarabic: "FC48", + meetorusquare: "334D", + mehiragana: "3081", + meizierasquare: "337E", + mekatakana: "30E1", + mekatakanahalfwidth: "FF92", + mem: "05DE", + memdagesh: "FB3E", + memdageshhebrew: "FB3E", + memhebrew: "05DE", + menarmenian: "0574", + merkhahebrew: "05A5", + merkhakefulahebrew: "05A6", + merkhakefulalefthebrew: "05A6", + merkhalefthebrew: "05A5", + mhook: "0271", + mhzsquare: "3392", + middledotkatakanahalfwidth: "FF65", + middot: "00B7", + mieumacirclekorean: "3272", + mieumaparenkorean: "3212", + mieumcirclekorean: "3264", + mieumkorean: "3141", + mieumpansioskorean: "3170", + mieumparenkorean: "3204", + mieumpieupkorean: "316E", + mieumsioskorean: "316F", + mihiragana: "307F", + mikatakana: "30DF", + mikatakanahalfwidth: "FF90", + minus: "2212", + minusbelowcmb: "0320", + minuscircle: "2296", + minusmod: "02D7", + minusplus: "2213", + minute: "2032", + miribaarusquare: "334A", + mirisquare: "3349", + mlonglegturned: "0270", + mlsquare: "3396", + mmcubedsquare: "33A3", + mmonospace: "FF4D", + mmsquaredsquare: "339F", + mohiragana: "3082", + mohmsquare: "33C1", + mokatakana: "30E2", + mokatakanahalfwidth: "FF93", + molsquare: "33D6", + momathai: "0E21", + moverssquare: "33A7", + moverssquaredsquare: "33A8", + mparen: "24A8", + mpasquare: "33AB", + mssquare: "33B3", + msuperior: "F6EF", + mturned: "026F", + mu: "00B5", + mu1: "00B5", + muasquare: "3382", + muchgreater: "226B", + muchless: "226A", + mufsquare: "338C", + mugreek: "03BC", + mugsquare: "338D", + muhiragana: "3080", + mukatakana: "30E0", + mukatakanahalfwidth: "FF91", + mulsquare: "3395", + multiply: "00D7", + mumsquare: "339B", + munahhebrew: "05A3", + munahlefthebrew: "05A3", + musicalnote: "266A", + musicalnotedbl: "266B", + musicflatsign: "266D", + musicsharpsign: "266F", + mussquare: "33B2", + muvsquare: "33B6", + muwsquare: "33BC", + mvmegasquare: "33B9", + mvsquare: "33B7", + mwmegasquare: "33BF", + mwsquare: "33BD", + n: "006E", + nabengali: "09A8", + nabla: "2207", + nacute: "0144", + nadeva: "0928", + nagujarati: "0AA8", + nagurmukhi: "0A28", + nahiragana: "306A", + nakatakana: "30CA", + nakatakanahalfwidth: "FF85", + napostrophe: "0149", + nasquare: "3381", + nbopomofo: "310B", + nbspace: "00A0", + ncaron: "0148", + ncedilla: "0146", + ncircle: "24DD", + ncircumflexbelow: "1E4B", + ncommaaccent: "0146", + ndotaccent: "1E45", + ndotbelow: "1E47", + nehiragana: "306D", + nekatakana: "30CD", + nekatakanahalfwidth: "FF88", + newsheqelsign: "20AA", + nfsquare: "338B", + ngabengali: "0999", + ngadeva: "0919", + ngagujarati: "0A99", + ngagurmukhi: "0A19", + ngonguthai: "0E07", + nhiragana: "3093", + nhookleft: "0272", + nhookretroflex: "0273", + nieunacirclekorean: "326F", + nieunaparenkorean: "320F", + nieuncieuckorean: "3135", + nieuncirclekorean: "3261", + nieunhieuhkorean: "3136", + nieunkorean: "3134", + nieunpansioskorean: "3168", + nieunparenkorean: "3201", + nieunsioskorean: "3167", + nieuntikeutkorean: "3166", + nihiragana: "306B", + nikatakana: "30CB", + nikatakanahalfwidth: "FF86", + nikhahitleftthai: "F899", + nikhahitthai: "0E4D", + nine: "0039", + ninearabic: "0669", + ninebengali: "09EF", + ninecircle: "2468", + ninecircleinversesansserif: "2792", + ninedeva: "096F", + ninegujarati: "0AEF", + ninegurmukhi: "0A6F", + ninehackarabic: "0669", + ninehangzhou: "3029", + nineideographicparen: "3228", + nineinferior: "2089", + ninemonospace: "FF19", + nineoldstyle: "F739", + nineparen: "247C", + nineperiod: "2490", + ninepersian: "06F9", + nineroman: "2178", + ninesuperior: "2079", + nineteencircle: "2472", + nineteenparen: "2486", + nineteenperiod: "249A", + ninethai: "0E59", + nj: "01CC", + njecyrillic: "045A", + nkatakana: "30F3", + nkatakanahalfwidth: "FF9D", + nlegrightlong: "019E", + nlinebelow: "1E49", + nmonospace: "FF4E", + nmsquare: "339A", + nnabengali: "09A3", + nnadeva: "0923", + nnagujarati: "0AA3", + nnagurmukhi: "0A23", + nnnadeva: "0929", + nohiragana: "306E", + nokatakana: "30CE", + nokatakanahalfwidth: "FF89", + nonbreakingspace: "00A0", + nonenthai: "0E13", + nonuthai: "0E19", + noonarabic: "0646", + noonfinalarabic: "FEE6", + noonghunnaarabic: "06BA", + noonghunnafinalarabic: "FB9F", 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, + nooninitialarabic: "FEE7", + noonjeeminitialarabic: "FCD2", + noonjeemisolatedarabic: "FC4B", + noonmedialarabic: "FEE8", + noonmeeminitialarabic: "FCD5", + noonmeemisolatedarabic: "FC4E", + noonnoonfinalarabic: "FC8D", + notcontains: "220C", + notelement: "2209", + notelementof: "2209", + notequal: "2260", + notgreater: "226F", + notgreaternorequal: "2271", + notgreaternorless: "2279", + notidentical: "2262", + notless: "226E", + notlessnorequal: "2270", + notparallel: "2226", + notprecedes: "2280", + notsubset: "2284", + notsucceeds: "2281", + notsuperset: "2285", + nowarmenian: "0576", + nparen: "24A9", + nssquare: "33B1", + nsuperior: "207F", + ntilde: "00F1", + nu: "03BD", + nuhiragana: "306C", + nukatakana: "30CC", + nukatakanahalfwidth: "FF87", + nuktabengali: "09BC", + nuktadeva: "093C", + nuktagujarati: "0ABC", + nuktagurmukhi: "0A3C", + numbersign: "0023", + numbersignmonospace: "FF03", + numbersignsmall: "FE5F", + numeralsigngreek: "0374", + numeralsignlowergreek: "0375", + numero: "2116", + nun: "05E0", + nundagesh: "FB40", + nundageshhebrew: "FB40", + nunhebrew: "05E0", + nvsquare: "33B5", + nwsquare: "33BB", + nyabengali: "099E", + nyadeva: "091E", + nyagujarati: "0A9E", + nyagurmukhi: "0A1E", + o: "006F", + oacute: "00F3", + oangthai: "0E2D", + obarred: "0275", + obarredcyrillic: "04E9", + obarreddieresiscyrillic: "04EB", + obengali: "0993", + obopomofo: "311B", + obreve: "014F", + ocandradeva: "0911", + ocandragujarati: "0A91", + ocandravowelsigndeva: "0949", + ocandravowelsigngujarati: "0AC9", + ocaron: "01D2", + ocircle: "24DE", + ocircumflex: "00F4", + ocircumflexacute: "1ED1", + ocircumflexdotbelow: "1ED9", + ocircumflexgrave: "1ED3", + ocircumflexhookabove: "1ED5", + ocircumflextilde: "1ED7", + ocyrillic: "043E", + odblacute: "0151", + odblgrave: "020D", + odeva: "0913", + odieresis: "00F6", + odieresiscyrillic: "04E7", + odotbelow: "1ECD", + oe: "0153", + oekorean: "315A", + ogonek: "02DB", + ogonekcmb: "0328", + ograve: "00F2", + ogujarati: "0A93", + oharmenian: "0585", + ohiragana: "304A", + ohookabove: "1ECF", + ohorn: "01A1", + ohornacute: "1EDB", + ohorndotbelow: "1EE3", + ohorngrave: "1EDD", + ohornhookabove: "1EDF", + ohorntilde: "1EE1", + ohungarumlaut: "0151", + oi: "01A3", + oinvertedbreve: "020F", + okatakana: "30AA", + okatakanahalfwidth: "FF75", + okorean: "3157", + olehebrew: "05AB", + omacron: "014D", + omacronacute: "1E53", + omacrongrave: "1E51", + omdeva: "0950", + omega: "03C9", + omega1: "03D6", + omegacyrillic: "0461", + omegalatinclosed: "0277", + omegaroundcyrillic: "047B", + omegatitlocyrillic: "047D", + omegatonos: "03CE", + omgujarati: "0AD0", + omicron: "03BF", + omicrontonos: "03CC", + omonospace: "FF4F", + one: "0031", + onearabic: "0661", + onebengali: "09E7", + onecircle: "2460", + onecircleinversesansserif: "278A", + onedeva: "0967", + onedotenleader: "2024", + oneeighth: "215B", + onefitted: "F6DC", + onegujarati: "0AE7", + onegurmukhi: "0A67", + onehackarabic: "0661", + onehalf: "00BD", + onehangzhou: "3021", + oneideographicparen: "3220", + oneinferior: "2081", + onemonospace: "FF11", + onenumeratorbengali: "09F4", + oneoldstyle: "F731", + oneparen: "2474", + oneperiod: "2488", + onepersian: "06F1", + onequarter: "00BC", + oneroman: "2170", + onesuperior: "00B9", + onethai: "0E51", + onethird: "2153", + oogonek: "01EB", + oogonekmacron: "01ED", + oogurmukhi: "0A13", + oomatragurmukhi: "0A4B", + oopen: "0254", + oparen: "24AA", + openbullet: "25E6", + option: "2325", + ordfeminine: "00AA", + ordmasculine: "00BA", + orthogonal: "221F", + oshortdeva: "0912", + oshortvowelsigndeva: "094A", + oslash: "00F8", + oslashacute: "01FF", + osmallhiragana: "3049", + osmallkatakana: "30A9", + osmallkatakanahalfwidth: "FF6B", + ostrokeacute: "01FF", + osuperior: "F6F0", + otcyrillic: "047F", + otilde: "00F5", + otildeacute: "1E4D", + otildedieresis: "1E4F", + oubopomofo: "3121", + overline: "203E", + overlinecenterline: "FE4A", + overlinecmb: "0305", + overlinedashed: "FE49", + overlinedblwavy: "FE4C", + overlinewavy: "FE4B", + overscore: "00AF", + ovowelsignbengali: "09CB", + ovowelsigndeva: "094B", + ovowelsigngujarati: "0ACB", + p: "0070", + paampssquare: "3380", + paasentosquare: "332B", + pabengali: "09AA", + pacute: "1E55", + padeva: "092A", + pagedown: "21DF", + pageup: "21DE", + pagujarati: "0AAA", + pagurmukhi: "0A2A", + pahiragana: "3071", + paiyannoithai: "0E2F", + pakatakana: "30D1", + palatalizationcyrilliccmb: "0484", + palochkacyrillic: "04C0", + pansioskorean: "317F", + paragraph: "00B6", + parallel: "2225", + parenleft: "0028", + parenleftaltonearabic: "FD3E", + parenleftbt: "F8ED", + parenleftex: "F8EC", + parenleftinferior: "208D", + parenleftmonospace: "FF08", + parenleftsmall: "FE59", + parenleftsuperior: "207D", + parenlefttp: "F8EB", + parenleftvertical: "FE35", + parenright: "0029", + parenrightaltonearabic: "FD3F", + parenrightbt: "F8F8", + parenrightex: "F8F7", + parenrightinferior: "208E", + parenrightmonospace: "FF09", + parenrightsmall: "FE5A", + parenrightsuperior: "207E", + parenrighttp: "F8F6", + parenrightvertical: "FE36", + partialdiff: "2202", + paseqhebrew: "05C0", + pashtahebrew: "0599", + pasquare: "33A9", + patah: "05B7", + patah11: "05B7", + patah1d: "05B7", + patah2a: "05B7", + patahhebrew: "05B7", + patahnarrowhebrew: "05B7", + patahquarterhebrew: "05B7", + patahwidehebrew: "05B7", + pazerhebrew: "05A1", + pbopomofo: "3106", + pcircle: "24DF", + pdotaccent: "1E57", + pe: "05E4", + pecyrillic: "043F", + pedagesh: "FB44", + pedageshhebrew: "FB44", + peezisquare: "333B", + pefinaldageshhebrew: "FB43", + peharabic: "067E", + peharmenian: "057A", + pehebrew: "05E4", + pehfinalarabic: "FB57", + pehinitialarabic: "FB58", + pehiragana: "307A", + pehmedialarabic: "FB59", + pekatakana: "30DA", + pemiddlehookcyrillic: "04A7", + perafehebrew: "FB4E", + percent: "0025", + percentarabic: "066A", + percentmonospace: "FF05", + percentsmall: "FE6A", + period: "002E", + periodarmenian: "0589", + periodcentered: "00B7", + periodhalfwidth: "FF61", + periodinferior: "F6E7", + periodmonospace: "FF0E", + periodsmall: "FE52", + periodsuperior: "F6E8", + perispomenigreekcmb: "0342", + perpendicular: "22A5", + perthousand: "2030", + peseta: "20A7", + pfsquare: "338A", + phabengali: "09AB", + phadeva: "092B", + phagujarati: "0AAB", + phagurmukhi: "0A2B", + phi: "03C6", + phi1: "03D5", + phieuphacirclekorean: "327A", + phieuphaparenkorean: "321A", + phieuphcirclekorean: "326C", + phieuphkorean: "314D", + phieuphparenkorean: "320C", + philatin: "0278", + phinthuthai: "0E3A", + phisymbolgreek: "03D5", + phook: "01A5", + phophanthai: "0E1E", + phophungthai: "0E1C", + phosamphaothai: "0E20", + pi: "03C0", + pieupacirclekorean: "3273", + pieupaparenkorean: "3213", + pieupcieuckorean: "3176", + pieupcirclekorean: "3265", + pieupkiyeokkorean: "3172", + pieupkorean: "3142", + pieupparenkorean: "3205", + pieupsioskiyeokkorean: "3174", + pieupsioskorean: "3144", + pieupsiostikeutkorean: "3175", + pieupthieuthkorean: "3177", + pieuptikeutkorean: "3173", + pihiragana: "3074", + pikatakana: "30D4", + pisymbolgreek: "03D6", + piwrarmenian: "0583", + plus: "002B", + plusbelowcmb: "031F", + pluscircle: "2295", + plusminus: "00B1", + plusmod: "02D6", + plusmonospace: "FF0B", + plussmall: "FE62", + plussuperior: "207A", + pmonospace: "FF50", + pmsquare: "33D8", + pohiragana: "307D", + pointingindexdownwhite: "261F", + pointingindexleftwhite: "261C", + pointingindexrightwhite: "261E", + pointingindexupwhite: "261D", + pokatakana: "30DD", + poplathai: "0E1B", + postalmark: "3012", + postalmarkface: "3020", + pparen: "24AB", + precedes: "227A", + prescription: "211E", + primemod: "02B9", + primereversed: "2035", + product: "220F", + projective: "2305", + prolongedkana: "30FC", + propellor: "2318", + propersubset: "2282", + propersuperset: "2283", + proportion: "2237", + proportional: "221D", + psi: "03C8", + psicyrillic: "0471", + psilipneumatacyrilliccmb: "0486", + pssquare: "33B0", + puhiragana: "3077", + pukatakana: "30D7", + pvsquare: "33B4", + pwsquare: "33BA", + q: "0071", + qadeva: "0958", + qadmahebrew: "05A8", + qafarabic: "0642", + qaffinalarabic: "FED6", + qafinitialarabic: "FED7", + qafmedialarabic: "FED8", + qamats: "05B8", + qamats10: "05B8", + qamats1a: "05B8", + qamats1c: "05B8", + qamats27: "05B8", + qamats29: "05B8", + qamats33: "05B8", + qamatsde: "05B8", + qamatshebrew: "05B8", + qamatsnarrowhebrew: "05B8", + qamatsqatanhebrew: "05B8", + qamatsqatannarrowhebrew: "05B8", + qamatsqatanquarterhebrew: "05B8", + qamatsqatanwidehebrew: "05B8", + qamatsquarterhebrew: "05B8", + qamatswidehebrew: "05B8", + qarneyparahebrew: "059F", + qbopomofo: "3111", + qcircle: "24E0", + qhook: "02A0", + qmonospace: "FF51", + qof: "05E7", + qofdagesh: "FB47", + qofdageshhebrew: "FB47", qofhatafpatah: "05E7 05B2", qofhatafpatahhebrew: "05E7 05B2", qofhatafsegol: "05E7 05B1", qofhatafsegolhebrew: "05E7 05B1", - qofhebrew: 0x05E7, + qofhebrew: "05E7", qofhiriq: "05E7 05B4", qofhiriqhebrew: "05E7 05B4", qofholam: "05E7 05B9", @@ -3172,89 +3172,89 @@ var GlyphsUnicode = { 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, + qparen: "24AC", + quarternote: "2669", + qubuts: "05BB", + qubuts18: "05BB", + qubuts25: "05BB", + qubuts31: "05BB", + qubutshebrew: "05BB", + qubutsnarrowhebrew: "05BB", + qubutsquarterhebrew: "05BB", + qubutswidehebrew: "05BB", + question: "003F", + questionarabic: "061F", + questionarmenian: "055E", + questiondown: "00BF", + questiondownsmall: "F7BF", + questiongreek: "037E", + questionmonospace: "FF1F", + questionsmall: "F73F", + quotedbl: "0022", + quotedblbase: "201E", + quotedblleft: "201C", + quotedblmonospace: "FF02", + quotedblprime: "301E", + quotedblprimereversed: "301D", + quotedblright: "201D", + quoteleft: "2018", + quoteleftreversed: "201B", + quotereversed: "201B", + quoteright: "2019", + quoterightn: "0149", + quotesinglbase: "201A", + quotesingle: "0027", + quotesinglemonospace: "FF07", + r: "0072", + raarmenian: "057C", + rabengali: "09B0", + racute: "0155", + radeva: "0930", + radical: "221A", + radicalex: "F8E5", + radoverssquare: "33AE", + radoverssquaredsquare: "33AF", + radsquare: "33AD", + rafe: "05BF", + rafehebrew: "05BF", + ragujarati: "0AB0", + ragurmukhi: "0A30", + rahiragana: "3089", + rakatakana: "30E9", + rakatakanahalfwidth: "FF97", + ralowerdiagonalbengali: "09F1", + ramiddlediagonalbengali: "09F0", + ramshorn: "0264", + ratio: "2236", + rbopomofo: "3116", + rcaron: "0159", + rcedilla: "0157", + rcircle: "24E1", + rcommaaccent: "0157", + rdblgrave: "0211", + rdotaccent: "1E59", + rdotbelow: "1E5B", + rdotbelowmacron: "1E5D", + referencemark: "203B", + reflexsubset: "2286", + reflexsuperset: "2287", + registered: "00AE", + registersans: "F8E8", + registerserif: "F6DA", + reharabic: "0631", + reharmenian: "0580", + rehfinalarabic: "FEAE", + rehiragana: "308C", rehyehaleflamarabic: "0631 FEF3 FE8E 0644", - rekatakana: 0x30EC, - rekatakanahalfwidth: 0xFF9A, - resh: 0x05E8, - reshdageshhebrew: 0xFB48, + rekatakana: "30EC", + rekatakanahalfwidth: "FF9A", + resh: "05E8", + reshdageshhebrew: "FB48", reshhatafpatah: "05E8 05B2", reshhatafpatahhebrew: "05E8 05B2", reshhatafsegol: "05E8 05B1", reshhatafsegolhebrew: "05E8 05B1", - reshhebrew: 0x05E8, + reshhebrew: "05E8", reshhiriq: "05E8 05B4", reshhiriqhebrew: "05E8 05B4", reshholam: "05E8 05B9", @@ -3271,1019 +3271,1019 @@ var GlyphsUnicode = { 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, + reversedtilde: "223D", + reviahebrew: "0597", + reviamugrashhebrew: "0597", + revlogicalnot: "2310", + rfishhook: "027E", + rfishhookreversed: "027F", + rhabengali: "09DD", + rhadeva: "095D", + rho: "03C1", + rhook: "027D", + rhookturned: "027B", + rhookturnedsuperior: "02B5", + rhosymbolgreek: "03F1", + rhotichookmod: "02DE", + rieulacirclekorean: "3271", + rieulaparenkorean: "3211", + rieulcirclekorean: "3263", + rieulhieuhkorean: "3140", + rieulkiyeokkorean: "313A", + rieulkiyeoksioskorean: "3169", + rieulkorean: "3139", + rieulmieumkorean: "313B", + rieulpansioskorean: "316C", + rieulparenkorean: "3203", + rieulphieuphkorean: "313F", + rieulpieupkorean: "313C", + rieulpieupsioskorean: "316B", + rieulsioskorean: "313D", + rieulthieuthkorean: "313E", + rieultikeutkorean: "316A", + rieulyeorinhieuhkorean: "316D", + rightangle: "221F", + righttackbelowcmb: "0319", + righttriangle: "22BF", + rihiragana: "308A", + rikatakana: "30EA", + rikatakanahalfwidth: "FF98", + ring: "02DA", + ringbelowcmb: "0325", + ringcmb: "030A", + ringhalfleft: "02BF", + ringhalfleftarmenian: "0559", + ringhalfleftbelowcmb: "031C", + ringhalfleftcentered: "02D3", + ringhalfright: "02BE", + ringhalfrightbelowcmb: "0339", + ringhalfrightcentered: "02D2", + rinvertedbreve: "0213", + rittorusquare: "3351", + rlinebelow: "1E5F", + rlongleg: "027C", + rlonglegturned: "027A", + rmonospace: "FF52", + rohiragana: "308D", + rokatakana: "30ED", + rokatakanahalfwidth: "FF9B", + roruathai: "0E23", + rparen: "24AD", + rrabengali: "09DC", + rradeva: "0931", + rragurmukhi: "0A5C", + rreharabic: "0691", + rrehfinalarabic: "FB8D", + rrvocalicbengali: "09E0", + rrvocalicdeva: "0960", + rrvocalicgujarati: "0AE0", + rrvocalicvowelsignbengali: "09C4", + rrvocalicvowelsigndeva: "0944", + rrvocalicvowelsigngujarati: "0AC4", + rsuperior: "F6F1", + rtblock: "2590", + rturned: "0279", + rturnedsuperior: "02B4", + ruhiragana: "308B", + rukatakana: "30EB", + rukatakanahalfwidth: "FF99", + rupeemarkbengali: "09F2", + rupeesignbengali: "09F3", + rupiah: "F6DD", + ruthai: "0E24", + rvocalicbengali: "098B", + rvocalicdeva: "090B", + rvocalicgujarati: "0A8B", + rvocalicvowelsignbengali: "09C3", + rvocalicvowelsigndeva: "0943", + rvocalicvowelsigngujarati: "0AC3", + s: "0073", + sabengali: "09B8", + sacute: "015B", + sacutedotaccent: "1E65", + sadarabic: "0635", + sadeva: "0938", + sadfinalarabic: "FEBA", + sadinitialarabic: "FEBB", + sadmedialarabic: "FEBC", + sagujarati: "0AB8", + sagurmukhi: "0A38", + sahiragana: "3055", + sakatakana: "30B5", + sakatakanahalfwidth: "FF7B", + sallallahoualayhewasallamarabic: "FDFA", + samekh: "05E1", + samekhdagesh: "FB41", + samekhdageshhebrew: "FB41", + samekhhebrew: "05E1", + saraaathai: "0E32", + saraaethai: "0E41", + saraaimaimalaithai: "0E44", + saraaimaimuanthai: "0E43", + saraamthai: "0E33", + saraathai: "0E30", + saraethai: "0E40", + saraiileftthai: "F886", + saraiithai: "0E35", + saraileftthai: "F885", + saraithai: "0E34", + saraothai: "0E42", + saraueeleftthai: "F888", + saraueethai: "0E37", + saraueleftthai: "F887", + sarauethai: "0E36", + sarauthai: "0E38", + sarauuthai: "0E39", + sbopomofo: "3119", + scaron: "0161", + scarondotaccent: "1E67", + scedilla: "015F", + schwa: "0259", + schwacyrillic: "04D9", + schwadieresiscyrillic: "04DB", + schwahook: "025A", + scircle: "24E2", + scircumflex: "015D", + scommaaccent: "0219", + sdotaccent: "1E61", + sdotbelow: "1E63", + sdotbelowdotaccent: "1E69", + seagullbelowcmb: "033C", + second: "2033", + secondtonechinese: "02CA", + section: "00A7", + seenarabic: "0633", + seenfinalarabic: "FEB2", + seeninitialarabic: "FEB3", + seenmedialarabic: "FEB4", + segol: "05B6", + segol13: "05B6", + segol1f: "05B6", + segol2c: "05B6", + segolhebrew: "05B6", + segolnarrowhebrew: "05B6", + segolquarterhebrew: "05B6", + segoltahebrew: "0592", + segolwidehebrew: "05B6", + seharmenian: "057D", + sehiragana: "305B", + sekatakana: "30BB", + sekatakanahalfwidth: "FF7E", + semicolon: "003B", + semicolonarabic: "061B", + semicolonmonospace: "FF1B", + semicolonsmall: "FE54", + semivoicedmarkkana: "309C", + semivoicedmarkkanahalfwidth: "FF9F", + sentisquare: "3322", + sentosquare: "3323", + seven: "0037", + sevenarabic: "0667", + sevenbengali: "09ED", + sevencircle: "2466", + sevencircleinversesansserif: "2790", + sevendeva: "096D", + seveneighths: "215E", + sevengujarati: "0AED", + sevengurmukhi: "0A6D", + sevenhackarabic: "0667", + sevenhangzhou: "3027", + sevenideographicparen: "3226", + seveninferior: "2087", + sevenmonospace: "FF17", + sevenoldstyle: "F737", + sevenparen: "247A", + sevenperiod: "248E", + sevenpersian: "06F7", + sevenroman: "2176", + sevensuperior: "2077", + seventeencircle: "2470", + seventeenparen: "2484", + seventeenperiod: "2498", + seventhai: "0E57", + sfthyphen: "00AD", + shaarmenian: "0577", + shabengali: "09B6", + shacyrillic: "0448", + shaddaarabic: "0651", + shaddadammaarabic: "FC61", + shaddadammatanarabic: "FC5E", + shaddafathaarabic: "FC60", 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, + shaddakasraarabic: "FC62", + shaddakasratanarabic: "FC5F", + shade: "2592", + shadedark: "2593", + shadelight: "2591", + shademedium: "2592", + shadeva: "0936", + shagujarati: "0AB6", + shagurmukhi: "0A36", + shalshelethebrew: "0593", + shbopomofo: "3115", + shchacyrillic: "0449", + sheenarabic: "0634", + sheenfinalarabic: "FEB6", + sheeninitialarabic: "FEB7", + sheenmedialarabic: "FEB8", + sheicoptic: "03E3", + sheqel: "20AA", + sheqelhebrew: "20AA", + sheva: "05B0", + sheva115: "05B0", + sheva15: "05B0", + sheva22: "05B0", + sheva2e: "05B0", + shevahebrew: "05B0", + shevanarrowhebrew: "05B0", + shevaquarterhebrew: "05B0", + shevawidehebrew: "05B0", + shhacyrillic: "04BB", + shimacoptic: "03ED", + shin: "05E9", + shindagesh: "FB49", + shindageshhebrew: "FB49", + shindageshshindot: "FB2C", + shindageshshindothebrew: "FB2C", + shindageshsindot: "FB2D", + shindageshsindothebrew: "FB2D", + shindothebrew: "05C1", + shinhebrew: "05E9", + shinshindot: "FB2A", + shinshindothebrew: "FB2A", + shinsindot: "FB2B", + shinsindothebrew: "FB2B", + shook: "0282", + sigma: "03C3", + sigma1: "03C2", + sigmafinal: "03C2", + sigmalunatesymbolgreek: "03F2", + sihiragana: "3057", + sikatakana: "30B7", + sikatakanahalfwidth: "FF7C", + siluqhebrew: "05BD", + siluqlefthebrew: "05BD", + similar: "223C", + sindothebrew: "05C2", + siosacirclekorean: "3274", + siosaparenkorean: "3214", + sioscieuckorean: "317E", + sioscirclekorean: "3266", + sioskiyeokkorean: "317A", + sioskorean: "3145", + siosnieunkorean: "317B", + siosparenkorean: "3206", + siospieupkorean: "317D", + siostikeutkorean: "317C", + six: "0036", + sixarabic: "0666", + sixbengali: "09EC", + sixcircle: "2465", + sixcircleinversesansserif: "278F", + sixdeva: "096C", + sixgujarati: "0AEC", + sixgurmukhi: "0A6C", + sixhackarabic: "0666", + sixhangzhou: "3026", + sixideographicparen: "3225", + sixinferior: "2086", + sixmonospace: "FF16", + sixoldstyle: "F736", + sixparen: "2479", + sixperiod: "248D", + sixpersian: "06F6", + sixroman: "2175", + sixsuperior: "2076", + sixteencircle: "246F", + sixteencurrencydenominatorbengali: "09F9", + sixteenparen: "2483", + sixteenperiod: "2497", + sixthai: "0E56", + slash: "002F", + slashmonospace: "FF0F", + slong: "017F", + slongdotaccent: "1E9B", + smileface: "263A", + smonospace: "FF53", + sofpasuqhebrew: "05C3", + softhyphen: "00AD", + softsigncyrillic: "044C", + sohiragana: "305D", + sokatakana: "30BD", + sokatakanahalfwidth: "FF7F", + soliduslongoverlaycmb: "0338", + solidusshortoverlaycmb: "0337", + sorusithai: "0E29", + sosalathai: "0E28", + sosothai: "0E0B", + sosuathai: "0E2A", + space: "0020", + spacehackarabic: "0020", + spade: "2660", + spadesuitblack: "2660", + spadesuitwhite: "2664", + sparen: "24AE", + squarebelowcmb: "033B", + squarecc: "33C4", + squarecm: "339D", + squarediagonalcrosshatchfill: "25A9", + squarehorizontalfill: "25A4", + squarekg: "338F", + squarekm: "339E", + squarekmcapital: "33CE", + squareln: "33D1", + squarelog: "33D2", + squaremg: "338E", + squaremil: "33D5", + squaremm: "339C", + squaremsquared: "33A1", + squareorthogonalcrosshatchfill: "25A6", + squareupperlefttolowerrightfill: "25A7", + squareupperrighttolowerleftfill: "25A8", + squareverticalfill: "25A5", + squarewhitewithsmallblack: "25A3", + srsquare: "33DB", + ssabengali: "09B7", + ssadeva: "0937", + ssagujarati: "0AB7", + ssangcieuckorean: "3149", + ssanghieuhkorean: "3185", + ssangieungkorean: "3180", + ssangkiyeokkorean: "3132", + ssangnieunkorean: "3165", + ssangpieupkorean: "3143", + ssangsioskorean: "3146", + ssangtikeutkorean: "3138", + ssuperior: "F6F2", + sterling: "00A3", + sterlingmonospace: "FFE1", + strokelongoverlaycmb: "0336", + strokeshortoverlaycmb: "0335", + subset: "2282", + subsetnotequal: "228A", + subsetorequal: "2286", + succeeds: "227B", + suchthat: "220B", + suhiragana: "3059", + sukatakana: "30B9", + sukatakanahalfwidth: "FF7D", + sukunarabic: "0652", + summation: "2211", + sun: "263C", + superset: "2283", + supersetnotequal: "228B", + supersetorequal: "2287", + svsquare: "33DC", + syouwaerasquare: "337C", + t: "0074", + tabengali: "09A4", + tackdown: "22A4", + tackleft: "22A3", + tadeva: "0924", + tagujarati: "0AA4", + tagurmukhi: "0A24", + taharabic: "0637", + tahfinalarabic: "FEC2", + tahinitialarabic: "FEC3", + tahiragana: "305F", + tahmedialarabic: "FEC4", + taisyouerasquare: "337D", + takatakana: "30BF", + takatakanahalfwidth: "FF80", + tatweelarabic: "0640", + tau: "03C4", + tav: "05EA", + tavdages: "FB4A", + tavdagesh: "FB4A", + tavdageshhebrew: "FB4A", + tavhebrew: "05EA", + tbar: "0167", + tbopomofo: "310A", + tcaron: "0165", + tccurl: "02A8", + tcedilla: "0163", + tcheharabic: "0686", + tchehfinalarabic: "FB7B", + tchehinitialarabic: "FB7C", + tchehmedialarabic: "FB7D", 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 + tcircle: "24E3", + tcircumflexbelow: "1E71", + tcommaaccent: "0163", + tdieresis: "1E97", + tdotaccent: "1E6B", + tdotbelow: "1E6D", + tecyrillic: "0442", + tedescendercyrillic: "04AD", + teharabic: "062A", + tehfinalarabic: "FE96", + tehhahinitialarabic: "FCA2", + tehhahisolatedarabic: "FC0C", + tehinitialarabic: "FE97", + tehiragana: "3066", + tehjeeminitialarabic: "FCA1", + tehjeemisolatedarabic: "FC0B", + tehmarbutaarabic: "0629", + tehmarbutafinalarabic: "FE94", + tehmedialarabic: "FE98", + tehmeeminitialarabic: "FCA4", + tehmeemisolatedarabic: "FC0E", + tehnoonfinalarabic: "FC73", + tekatakana: "30C6", + tekatakanahalfwidth: "FF83", + telephone: "2121", + telephoneblack: "260E", + telishagedolahebrew: "05A0", + telishaqetanahebrew: "05A9", + tencircle: "2469", + tenideographicparen: "3229", + tenparen: "247D", + tenperiod: "2491", + tenroman: "2179", + tesh: "02A7", + tet: "05D8", + tetdagesh: "FB38", + tetdageshhebrew: "FB38", + tethebrew: "05D8", + tetsecyrillic: "04B5", + tevirhebrew: "059B", + tevirlefthebrew: "059B", + thabengali: "09A5", + thadeva: "0925", + thagujarati: "0AA5", + thagurmukhi: "0A25", + thalarabic: "0630", + thalfinalarabic: "FEAC", + thanthakhatlowleftthai: "F898", + thanthakhatlowrightthai: "F897", + thanthakhatthai: "0E4C", + thanthakhatupperleftthai: "F896", + theharabic: "062B", + thehfinalarabic: "FE9A", + thehinitialarabic: "FE9B", + thehmedialarabic: "FE9C", + thereexists: "2203", + therefore: "2234", + theta: "03B8", + theta1: "03D1", + thetasymbolgreek: "03D1", + thieuthacirclekorean: "3279", + thieuthaparenkorean: "3219", + thieuthcirclekorean: "326B", + thieuthkorean: "314C", + thieuthparenkorean: "320B", + thirteencircle: "246C", + thirteenparen: "2480", + thirteenperiod: "2494", + thonangmonthothai: "0E11", + thook: "01AD", + thophuthaothai: "0E12", + thorn: "00FE", + thothahanthai: "0E17", + thothanthai: "0E10", + thothongthai: "0E18", + thothungthai: "0E16", + thousandcyrillic: "0482", + thousandsseparatorarabic: "066C", + thousandsseparatorpersian: "066C", + three: "0033", + threearabic: "0663", + threebengali: "09E9", + threecircle: "2462", + threecircleinversesansserif: "278C", + threedeva: "0969", + threeeighths: "215C", + threegujarati: "0AE9", + threegurmukhi: "0A69", + threehackarabic: "0663", + threehangzhou: "3023", + threeideographicparen: "3222", + threeinferior: "2083", + threemonospace: "FF13", + threenumeratorbengali: "09F6", + threeoldstyle: "F733", + threeparen: "2476", + threeperiod: "248A", + threepersian: "06F3", + threequarters: "00BE", + threequartersemdash: "F6DE", + threeroman: "2172", + threesuperior: "00B3", + threethai: "0E53", + thzsquare: "3394", + tihiragana: "3061", + tikatakana: "30C1", + tikatakanahalfwidth: "FF81", + tikeutacirclekorean: "3270", + tikeutaparenkorean: "3210", + tikeutcirclekorean: "3262", + tikeutkorean: "3137", + tikeutparenkorean: "3202", + tilde: "02DC", + tildebelowcmb: "0330", + tildecmb: "0303", + tildecomb: "0303", + tildedoublecmb: "0360", + tildeoperator: "223C", + tildeoverlaycmb: "0334", + tildeverticalcmb: "033E", + timescircle: "2297", + tipehahebrew: "0596", + tipehalefthebrew: "0596", + tippigurmukhi: "0A70", + titlocyrilliccmb: "0483", + tiwnarmenian: "057F", + tlinebelow: "1E6F", + tmonospace: "FF54", + toarmenian: "0569", + tohiragana: "3068", + tokatakana: "30C8", + tokatakanahalfwidth: "FF84", + tonebarextrahighmod: "02E5", + tonebarextralowmod: "02E9", + tonebarhighmod: "02E6", + tonebarlowmod: "02E8", + tonebarmidmod: "02E7", + tonefive: "01BD", + tonesix: "0185", + tonetwo: "01A8", + tonos: "0384", + tonsquare: "3327", + topatakthai: "0E0F", + tortoiseshellbracketleft: "3014", + tortoiseshellbracketleftsmall: "FE5D", + tortoiseshellbracketleftvertical: "FE39", + tortoiseshellbracketright: "3015", + tortoiseshellbracketrightsmall: "FE5E", + tortoiseshellbracketrightvertical: "FE3A", + totaothai: "0E15", + tpalatalhook: "01AB", + tparen: "24AF", + trademark: "2122", + trademarksans: "F8EA", + trademarkserif: "F6DB", + tretroflexhook: "0288", + triagdn: "25BC", + triaglf: "25C4", + triagrt: "25BA", + triagup: "25B2", + ts: "02A6", + tsadi: "05E6", + tsadidagesh: "FB46", + tsadidageshhebrew: "FB46", + tsadihebrew: "05E6", + tsecyrillic: "0446", + tsere: "05B5", + tsere12: "05B5", + tsere1e: "05B5", + tsere2b: "05B5", + tserehebrew: "05B5", + tserenarrowhebrew: "05B5", + tserequarterhebrew: "05B5", + tserewidehebrew: "05B5", + tshecyrillic: "045B", + tsuperior: "F6F3", + ttabengali: "099F", + ttadeva: "091F", + ttagujarati: "0A9F", + ttagurmukhi: "0A1F", + tteharabic: "0679", + ttehfinalarabic: "FB67", + ttehinitialarabic: "FB68", + ttehmedialarabic: "FB69", + tthabengali: "09A0", + tthadeva: "0920", + tthagujarati: "0AA0", + tthagurmukhi: "0A20", + tturned: "0287", + tuhiragana: "3064", + tukatakana: "30C4", + tukatakanahalfwidth: "FF82", + tusmallhiragana: "3063", + tusmallkatakana: "30C3", + tusmallkatakanahalfwidth: "FF6F", + twelvecircle: "246B", + twelveparen: "247F", + twelveperiod: "2493", + twelveroman: "217B", + twentycircle: "2473", + twentyhangzhou: "5344", + twentyparen: "2487", + twentyperiod: "249B", + two: "0032", + twoarabic: "0662", + twobengali: "09E8", + twocircle: "2461", + twocircleinversesansserif: "278B", + twodeva: "0968", + twodotenleader: "2025", + twodotleader: "2025", + twodotleadervertical: "FE30", + twogujarati: "0AE8", + twogurmukhi: "0A68", + twohackarabic: "0662", + twohangzhou: "3022", + twoideographicparen: "3221", + twoinferior: "2082", + twomonospace: "FF12", + twonumeratorbengali: "09F5", + twooldstyle: "F732", + twoparen: "2475", + twoperiod: "2489", + twopersian: "06F2", + tworoman: "2171", + twostroke: "01BB", + twosuperior: "00B2", + twothai: "0E52", + twothirds: "2154", + u: "0075", + uacute: "00FA", + ubar: "0289", + ubengali: "0989", + ubopomofo: "3128", + ubreve: "016D", + ucaron: "01D4", + ucircle: "24E4", + ucircumflex: "00FB", + ucircumflexbelow: "1E77", + ucyrillic: "0443", + udattadeva: "0951", + udblacute: "0171", + udblgrave: "0215", + udeva: "0909", + udieresis: "00FC", + udieresisacute: "01D8", + udieresisbelow: "1E73", + udieresiscaron: "01DA", + udieresiscyrillic: "04F1", + udieresisgrave: "01DC", + udieresismacron: "01D6", + udotbelow: "1EE5", + ugrave: "00F9", + ugujarati: "0A89", + ugurmukhi: "0A09", + uhiragana: "3046", + uhookabove: "1EE7", + uhorn: "01B0", + uhornacute: "1EE9", + uhorndotbelow: "1EF1", + uhorngrave: "1EEB", + uhornhookabove: "1EED", + uhorntilde: "1EEF", + uhungarumlaut: "0171", + uhungarumlautcyrillic: "04F3", + uinvertedbreve: "0217", + ukatakana: "30A6", + ukatakanahalfwidth: "FF73", + ukcyrillic: "0479", + ukorean: "315C", + umacron: "016B", + umacroncyrillic: "04EF", + umacrondieresis: "1E7B", + umatragurmukhi: "0A41", + umonospace: "FF55", + underscore: "005F", + underscoredbl: "2017", + underscoremonospace: "FF3F", + underscorevertical: "FE33", + underscorewavy: "FE4F", + union: "222A", + universal: "2200", + uogonek: "0173", + uparen: "24B0", + upblock: "2580", + upperdothebrew: "05C4", + upsilon: "03C5", + upsilondieresis: "03CB", + upsilondieresistonos: "03B0", + upsilonlatin: "028A", + upsilontonos: "03CD", + uptackbelowcmb: "031D", + uptackmod: "02D4", + uragurmukhi: "0A73", + uring: "016F", + ushortcyrillic: "045E", + usmallhiragana: "3045", + usmallkatakana: "30A5", + usmallkatakanahalfwidth: "FF69", + ustraightcyrillic: "04AF", + ustraightstrokecyrillic: "04B1", + utilde: "0169", + utildeacute: "1E79", + utildebelow: "1E75", + uubengali: "098A", + uudeva: "090A", + uugujarati: "0A8A", + uugurmukhi: "0A0A", + uumatragurmukhi: "0A42", + uuvowelsignbengali: "09C2", + uuvowelsigndeva: "0942", + uuvowelsigngujarati: "0AC2", + uvowelsignbengali: "09C1", + uvowelsigndeva: "0941", + uvowelsigngujarati: "0AC1", + v: "0076", + vadeva: "0935", + vagujarati: "0AB5", + vagurmukhi: "0A35", + vakatakana: "30F7", + vav: "05D5", + vavdagesh: "FB35", + vavdagesh65: "FB35", + vavdageshhebrew: "FB35", + vavhebrew: "05D5", + vavholam: "FB4B", + vavholamhebrew: "FB4B", + vavvavhebrew: "05F0", + vavyodhebrew: "05F1", + vcircle: "24E5", + vdotbelow: "1E7F", + vecyrillic: "0432", + veharabic: "06A4", + vehfinalarabic: "FB6B", + vehinitialarabic: "FB6C", + vehmedialarabic: "FB6D", + vekatakana: "30F9", + venus: "2640", + verticalbar: "007C", + verticallineabovecmb: "030D", + verticallinebelowcmb: "0329", + verticallinelowmod: "02CC", + verticallinemod: "02C8", + vewarmenian: "057E", + vhook: "028B", + vikatakana: "30F8", + viramabengali: "09CD", + viramadeva: "094D", + viramagujarati: "0ACD", + visargabengali: "0983", + visargadeva: "0903", + visargagujarati: "0A83", + vmonospace: "FF56", + voarmenian: "0578", + voicediterationhiragana: "309E", + voicediterationkatakana: "30FE", + voicedmarkkana: "309B", + voicedmarkkanahalfwidth: "FF9E", + vokatakana: "30FA", + vparen: "24B1", + vtilde: "1E7D", + vturned: "028C", + vuhiragana: "3094", + vukatakana: "30F4", + w: "0077", + wacute: "1E83", + waekorean: "3159", + wahiragana: "308F", + wakatakana: "30EF", + wakatakanahalfwidth: "FF9C", + wakorean: "3158", + wasmallhiragana: "308E", + wasmallkatakana: "30EE", + wattosquare: "3357", + wavedash: "301C", + wavyunderscorevertical: "FE34", + wawarabic: "0648", + wawfinalarabic: "FEEE", + wawhamzaabovearabic: "0624", + wawhamzaabovefinalarabic: "FE86", + wbsquare: "33DD", + wcircle: "24E6", + wcircumflex: "0175", + wdieresis: "1E85", + wdotaccent: "1E87", + wdotbelow: "1E89", + wehiragana: "3091", + weierstrass: "2118", + wekatakana: "30F1", + wekorean: "315E", + weokorean: "315D", + wgrave: "1E81", + whitebullet: "25E6", + whitecircle: "25CB", + whitecircleinverse: "25D9", + whitecornerbracketleft: "300E", + whitecornerbracketleftvertical: "FE43", + whitecornerbracketright: "300F", + whitecornerbracketrightvertical: "FE44", + whitediamond: "25C7", + whitediamondcontainingblacksmalldiamond: "25C8", + whitedownpointingsmalltriangle: "25BF", + whitedownpointingtriangle: "25BD", + whiteleftpointingsmalltriangle: "25C3", + whiteleftpointingtriangle: "25C1", + whitelenticularbracketleft: "3016", + whitelenticularbracketright: "3017", + whiterightpointingsmalltriangle: "25B9", + whiterightpointingtriangle: "25B7", + whitesmallsquare: "25AB", + whitesmilingface: "263A", + whitesquare: "25A1", + whitestar: "2606", + whitetelephone: "260F", + whitetortoiseshellbracketleft: "3018", + whitetortoiseshellbracketright: "3019", + whiteuppointingsmalltriangle: "25B5", + whiteuppointingtriangle: "25B3", + wihiragana: "3090", + wikatakana: "30F0", + wikorean: "315F", + wmonospace: "FF57", + wohiragana: "3092", + wokatakana: "30F2", + wokatakanahalfwidth: "FF66", + won: "20A9", + wonmonospace: "FFE6", + wowaenthai: "0E27", + wparen: "24B2", + wring: "1E98", + wsuperior: "02B7", + wturned: "028D", + wynn: "01BF", + x: "0078", + xabovecmb: "033D", + xbopomofo: "3112", + xcircle: "24E7", + xdieresis: "1E8D", + xdotaccent: "1E8B", + xeharmenian: "056D", + xi: "03BE", + xmonospace: "FF58", + xparen: "24B3", + xsuperior: "02E3", + y: "0079", + yaadosquare: "334E", + yabengali: "09AF", + yacute: "00FD", + yadeva: "092F", + yaekorean: "3152", + yagujarati: "0AAF", + yagurmukhi: "0A2F", + yahiragana: "3084", + yakatakana: "30E4", + yakatakanahalfwidth: "FF94", + yakorean: "3151", + yamakkanthai: "0E4E", + yasmallhiragana: "3083", + yasmallkatakana: "30E3", + yasmallkatakanahalfwidth: "FF6C", + yatcyrillic: "0463", + ycircle: "24E8", + ycircumflex: "0177", + ydieresis: "00FF", + ydotaccent: "1E8F", + ydotbelow: "1EF5", + yeharabic: "064A", + yehbarreearabic: "06D2", + yehbarreefinalarabic: "FBAF", + yehfinalarabic: "FEF2", + yehhamzaabovearabic: "0626", + yehhamzaabovefinalarabic: "FE8A", + yehhamzaaboveinitialarabic: "FE8B", + yehhamzaabovemedialarabic: "FE8C", + yehinitialarabic: "FEF3", + yehmedialarabic: "FEF4", + yehmeeminitialarabic: "FCDD", + yehmeemisolatedarabic: "FC58", + yehnoonfinalarabic: "FC94", + yehthreedotsbelowarabic: "06D1", + yekorean: "3156", + yen: "00A5", + yenmonospace: "FFE5", + yeokorean: "3155", + yeorinhieuhkorean: "3186", + yerahbenyomohebrew: "05AA", + yerahbenyomolefthebrew: "05AA", + yericyrillic: "044B", + yerudieresiscyrillic: "04F9", + yesieungkorean: "3181", + yesieungpansioskorean: "3183", + yesieungsioskorean: "3182", + yetivhebrew: "059A", + ygrave: "1EF3", + yhook: "01B4", + yhookabove: "1EF7", + yiarmenian: "0575", + yicyrillic: "0457", + yikorean: "3162", + yinyang: "262F", + yiwnarmenian: "0582", + ymonospace: "FF59", + yod: "05D9", + yoddagesh: "FB39", + yoddageshhebrew: "FB39", + yodhebrew: "05D9", + yodyodhebrew: "05F2", + yodyodpatahhebrew: "FB1F", + yohiragana: "3088", + yoikorean: "3189", + yokatakana: "30E8", + yokatakanahalfwidth: "FF96", + yokorean: "315B", + yosmallhiragana: "3087", + yosmallkatakana: "30E7", + yosmallkatakanahalfwidth: "FF6E", + yotgreek: "03F3", + yoyaekorean: "3188", + yoyakorean: "3187", + yoyakthai: "0E22", + yoyingthai: "0E0D", + yparen: "24B4", + ypogegrammeni: "037A", + ypogegrammenigreekcmb: "0345", + yr: "01A6", + yring: "1E99", + ysuperior: "02B8", + ytilde: "1EF9", + yturned: "028E", + yuhiragana: "3086", + yuikorean: "318C", + yukatakana: "30E6", + yukatakanahalfwidth: "FF95", + yukorean: "3160", + yusbigcyrillic: "046B", + yusbigiotifiedcyrillic: "046D", + yuslittlecyrillic: "0467", + yuslittleiotifiedcyrillic: "0469", + yusmallhiragana: "3085", + yusmallkatakana: "30E5", + yusmallkatakanahalfwidth: "FF6D", + yuyekorean: "318B", + yuyeokorean: "318A", + yyabengali: "09DF", + yyadeva: "095F", + z: "007A", + zaarmenian: "0566", + zacute: "017A", + zadeva: "095B", + zagurmukhi: "0A5B", + zaharabic: "0638", + zahfinalarabic: "FEC6", + zahinitialarabic: "FEC7", + zahiragana: "3056", + zahmedialarabic: "FEC8", + zainarabic: "0632", + zainfinalarabic: "FEB0", + zakatakana: "30B6", + zaqefgadolhebrew: "0595", + zaqefqatanhebrew: "0594", + zarqahebrew: "0598", + zayin: "05D6", + zayindagesh: "FB36", + zayindageshhebrew: "FB36", + zayinhebrew: "05D6", + zbopomofo: "3117", + zcaron: "017E", + zcircle: "24E9", + zcircumflex: "1E91", + zcurl: "0291", + zdot: "017C", + zdotaccent: "017C", + zdotbelow: "1E93", + zecyrillic: "0437", + zedescendercyrillic: "0499", + zedieresiscyrillic: "04DF", + zehiragana: "305C", + zekatakana: "30BC", + zero: "0030", + zeroarabic: "0660", + zerobengali: "09E6", + zerodeva: "0966", + zerogujarati: "0AE6", + zerogurmukhi: "0A66", + zerohackarabic: "0660", + zeroinferior: "2080", + zeromonospace: "FF10", + zerooldstyle: "F730", + zeropersian: "06F0", + zerosuperior: "2070", + zerothai: "0E50", + zerowidthjoiner: "FEFF", + zerowidthnonjoiner: "200C", + zerowidthspace: "200B", + zeta: "03B6", + zhbopomofo: "3113", + zhearmenian: "056A", + zhebrevecyrillic: "04C2", + zhecyrillic: "0436", + zhedescendercyrillic: "0497", + zhedieresiscyrillic: "04DD", + zihiragana: "3058", + zikatakana: "30B8", + zinorhebrew: "05AE", + zlinebelow: "1E95", + zmonospace: "FF5A", + zohiragana: "305E", + zokatakana: "30BE", + zparen: "24B5", + zretroflexhook: "0290", + zstroke: "01B6", + zuhiragana: "305A", + zukatakana: "30BA" }; // Add missing glyphs from the original Adobe's list -GlyphsUnicode["angbracketleft"] = 0x3008; -GlyphsUnicode["angbracketright"] = 0x3009; -GlyphsUnicode["circlecopyrt"] = 0x00A9; +GlyphsUnicode["angbracketleft"] = "3008"; +GlyphsUnicode["angbracketright"] = "3009"; +GlyphsUnicode["circlecopyrt"] = "00A9"; From 416fc7865fe2963a83b7819f608852556f7ebdb5 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Fri, 17 Jun 2011 01:03:21 -0700 Subject: [PATCH 76/77] 2nd attempt to make glyph list integers --- fonts.js | 8 +- glyphlist.js | 8406 +++++++++++++++++++++++++------------------------- 2 files changed, 4205 insertions(+), 4209 deletions(-) diff --git a/fonts.js b/fonts.js index 2db7e745f..5390abba4 100644 --- a/fonts.js +++ b/fonts.js @@ -40,7 +40,7 @@ var Fonts = { unicodeFromCode: function fonts_unicodeFromCode(aCode) { var unicode = GlyphsUnicode[this.active.encoding[aCode]]; - return unicode ? "0x" + unicode : aCode; + return unicode ? unicode : aCode; } }; @@ -175,7 +175,7 @@ Font.prototype = { // see what's happening if (debug) { for (var i = 0; i < charset.length; i++) { - var unicode = new Number("0x" + GlyphsUnicode[charset[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); @@ -1183,10 +1183,6 @@ CFF.prototype = { if (glyph != ".notdef") warn(glyph + " does not have an entry in the glyphs unicode dictionary"); } else { - var b1 = parseInt("0x" + unicode[0] + unicode[1]); - var b2 = parseInt("0x" + unicode[2] + unicode[3]); - unicode = FontsUtils.bytesToInteger([b1, b2]); - charstrings.push({ glyph: glyph, unicode: unicode, diff --git a/glyphlist.js b/glyphlist.js index e147f6c8a..f5a11b522 100644 --- a/glyphlist.js +++ b/glyphlist.js @@ -1,1510 +1,1510 @@ var GlyphsUnicode = { - A: "0041", - AE: "00C6", - AEacute: "01FC", - AEmacron: "01E2", - AEsmall: "F7E6", - Aacute: "00C1", - Aacutesmall: "F7E1", - Abreve: "0102", - Abreveacute: "1EAE", - Abrevecyrillic: "04D0", - Abrevedotbelow: "1EB6", - Abrevegrave: "1EB0", - Abrevehookabove: "1EB2", - Abrevetilde: "1EB4", - Acaron: "01CD", - Acircle: "24B6", - Acircumflex: "00C2", - Acircumflexacute: "1EA4", - Acircumflexdotbelow: "1EAC", - Acircumflexgrave: "1EA6", - Acircumflexhookabove: "1EA8", - Acircumflexsmall: "F7E2", - Acircumflextilde: "1EAA", - Acute: "F6C9", - Acutesmall: "F7B4", - Acyrillic: "0410", - Adblgrave: "0200", - Adieresis: "00C4", - Adieresiscyrillic: "04D2", - Adieresismacron: "01DE", - Adieresissmall: "F7E4", - Adotbelow: "1EA0", - Adotmacron: "01E0", - Agrave: "00C0", - Agravesmall: "F7E0", - Ahookabove: "1EA2", - Aiecyrillic: "04D4", - Ainvertedbreve: "0202", - Alpha: "0391", - Alphatonos: "0386", - Amacron: "0100", - Amonospace: "FF21", - Aogonek: "0104", - Aring: "00C5", - Aringacute: "01FA", - Aringbelow: "1E00", - Aringsmall: "F7E5", - Asmall: "F761", - Atilde: "00C3", - Atildesmall: "F7E3", - Aybarmenian: "0531", - B: "0042", - Bcircle: "24B7", - Bdotaccent: "1E02", - Bdotbelow: "1E04", - Becyrillic: "0411", - Benarmenian: "0532", - Beta: "0392", - Bhook: "0181", - Blinebelow: "1E06", - Bmonospace: "FF22", - Brevesmall: "F6F4", - Bsmall: "F762", - Btopbar: "0182", - C: "0043", - Caarmenian: "053E", - Cacute: "0106", - Caron: "F6CA", - Caronsmall: "F6F5", - Ccaron: "010C", - Ccedilla: "00C7", - Ccedillaacute: "1E08", - Ccedillasmall: "F7E7", - Ccircle: "24B8", - Ccircumflex: "0108", - Cdot: "010A", - Cdotaccent: "010A", - Cedillasmall: "F7B8", - Chaarmenian: "0549", - Cheabkhasiancyrillic: "04BC", - Checyrillic: "0427", - Chedescenderabkhasiancyrillic: "04BE", - Chedescendercyrillic: "04B6", - Chedieresiscyrillic: "04F4", - Cheharmenian: "0543", - Chekhakassiancyrillic: "04CB", - Cheverticalstrokecyrillic: "04B8", - Chi: "03A7", - Chook: "0187", - Circumflexsmall: "F6F6", - Cmonospace: "FF23", - Coarmenian: "0551", - Csmall: "F763", - D: "0044", - DZ: "01F1", - DZcaron: "01C4", - Daarmenian: "0534", - Dafrican: "0189", - Dcaron: "010E", - Dcedilla: "1E10", - Dcircle: "24B9", - Dcircumflexbelow: "1E12", - Dcroat: "0110", - Ddotaccent: "1E0A", - Ddotbelow: "1E0C", - Decyrillic: "0414", - Deicoptic: "03EE", - Delta: "2206", - Deltagreek: "0394", - Dhook: "018A", - Dieresis: "F6CB", - DieresisAcute: "F6CC", - DieresisGrave: "F6CD", - Dieresissmall: "F7A8", - Digammagreek: "03DC", - Djecyrillic: "0402", - Dlinebelow: "1E0E", - Dmonospace: "FF24", - Dotaccentsmall: "F6F7", - Dslash: "0110", - Dsmall: "F764", - Dtopbar: "018B", - Dz: "01F2", - Dzcaron: "01C5", - Dzeabkhasiancyrillic: "04E0", - Dzecyrillic: "0405", - Dzhecyrillic: "040F", - E: "0045", - Eacute: "00C9", - Eacutesmall: "F7E9", - Ebreve: "0114", - Ecaron: "011A", - Ecedillabreve: "1E1C", - Echarmenian: "0535", - Ecircle: "24BA", - Ecircumflex: "00CA", - Ecircumflexacute: "1EBE", - Ecircumflexbelow: "1E18", - Ecircumflexdotbelow: "1EC6", - Ecircumflexgrave: "1EC0", - Ecircumflexhookabove: "1EC2", - Ecircumflexsmall: "F7EA", - Ecircumflextilde: "1EC4", - Ecyrillic: "0404", - Edblgrave: "0204", - Edieresis: "00CB", - Edieresissmall: "F7EB", - Edot: "0116", - Edotaccent: "0116", - Edotbelow: "1EB8", - Efcyrillic: "0424", - Egrave: "00C8", - Egravesmall: "F7E8", - Eharmenian: "0537", - Ehookabove: "1EBA", - Eightroman: "2167", - Einvertedbreve: "0206", - Eiotifiedcyrillic: "0464", - Elcyrillic: "041B", - Elevenroman: "216A", - Emacron: "0112", - Emacronacute: "1E16", - Emacrongrave: "1E14", - Emcyrillic: "041C", - Emonospace: "FF25", - Encyrillic: "041D", - Endescendercyrillic: "04A2", - Eng: "014A", - Enghecyrillic: "04A4", - Enhookcyrillic: "04C7", - Eogonek: "0118", - Eopen: "0190", - Epsilon: "0395", - Epsilontonos: "0388", - Ercyrillic: "0420", - Ereversed: "018E", - Ereversedcyrillic: "042D", - Escyrillic: "0421", - Esdescendercyrillic: "04AA", - Esh: "01A9", - Esmall: "F765", - Eta: "0397", - Etarmenian: "0538", - Etatonos: "0389", - Eth: "00D0", - Ethsmall: "F7F0", - Etilde: "1EBC", - Etildebelow: "1E1A", - Euro: "20AC", - Ezh: "01B7", - Ezhcaron: "01EE", - Ezhreversed: "01B8", - F: "0046", - Fcircle: "24BB", - Fdotaccent: "1E1E", - Feharmenian: "0556", - Feicoptic: "03E4", - Fhook: "0191", - Fitacyrillic: "0472", - Fiveroman: "2164", - Fmonospace: "FF26", - Fourroman: "2163", - Fsmall: "F766", - G: "0047", - GBsquare: "3387", - Gacute: "01F4", - Gamma: "0393", - Gammaafrican: "0194", - Gangiacoptic: "03EA", - Gbreve: "011E", - Gcaron: "01E6", - Gcedilla: "0122", - Gcircle: "24BC", - Gcircumflex: "011C", - Gcommaaccent: "0122", - Gdot: "0120", - Gdotaccent: "0120", - Gecyrillic: "0413", - Ghadarmenian: "0542", - Ghemiddlehookcyrillic: "0494", - Ghestrokecyrillic: "0492", - Gheupturncyrillic: "0490", - Ghook: "0193", - Gimarmenian: "0533", - Gjecyrillic: "0403", - Gmacron: "1E20", - Gmonospace: "FF27", - Grave: "F6CE", - Gravesmall: "F760", - Gsmall: "F767", - Gsmallhook: "029B", - Gstroke: "01E4", - H: "0048", - H18533: "25CF", - H18543: "25AA", - H18551: "25AB", - H22073: "25A1", - HPsquare: "33CB", - Haabkhasiancyrillic: "04A8", - Hadescendercyrillic: "04B2", - Hardsigncyrillic: "042A", - Hbar: "0126", - Hbrevebelow: "1E2A", - Hcedilla: "1E28", - Hcircle: "24BD", - Hcircumflex: "0124", - Hdieresis: "1E26", - Hdotaccent: "1E22", - Hdotbelow: "1E24", - Hmonospace: "FF28", - Hoarmenian: "0540", - Horicoptic: "03E8", - Hsmall: "F768", - Hungarumlaut: "F6CF", - Hungarumlautsmall: "F6F8", - Hzsquare: "3390", - I: "0049", - IAcyrillic: "042F", - IJ: "0132", - IUcyrillic: "042E", - Iacute: "00CD", - Iacutesmall: "F7ED", - Ibreve: "012C", - Icaron: "01CF", - Icircle: "24BE", - Icircumflex: "00CE", - Icircumflexsmall: "F7EE", - Icyrillic: "0406", - Idblgrave: "0208", - Idieresis: "00CF", - Idieresisacute: "1E2E", - Idieresiscyrillic: "04E4", - Idieresissmall: "F7EF", - Idot: "0130", - Idotaccent: "0130", - Idotbelow: "1ECA", - Iebrevecyrillic: "04D6", - Iecyrillic: "0415", - Ifraktur: "2111", - Igrave: "00CC", - Igravesmall: "F7EC", - Ihookabove: "1EC8", - Iicyrillic: "0418", - Iinvertedbreve: "020A", - Iishortcyrillic: "0419", - Imacron: "012A", - Imacroncyrillic: "04E2", - Imonospace: "FF29", - Iniarmenian: "053B", - Iocyrillic: "0401", - Iogonek: "012E", - Iota: "0399", - Iotaafrican: "0196", - Iotadieresis: "03AA", - Iotatonos: "038A", - Ismall: "F769", - Istroke: "0197", - Itilde: "0128", - Itildebelow: "1E2C", - Izhitsacyrillic: "0474", - Izhitsadblgravecyrillic: "0476", - J: "004A", - Jaarmenian: "0541", - Jcircle: "24BF", - Jcircumflex: "0134", - Jecyrillic: "0408", - Jheharmenian: "054B", - Jmonospace: "FF2A", - Jsmall: "F76A", - K: "004B", - KBsquare: "3385", - KKsquare: "33CD", - Kabashkircyrillic: "04A0", - Kacute: "1E30", - Kacyrillic: "041A", - Kadescendercyrillic: "049A", - Kahookcyrillic: "04C3", - Kappa: "039A", - Kastrokecyrillic: "049E", - Kaverticalstrokecyrillic: "049C", - Kcaron: "01E8", - Kcedilla: "0136", - Kcircle: "24C0", - Kcommaaccent: "0136", - Kdotbelow: "1E32", - Keharmenian: "0554", - Kenarmenian: "053F", - Khacyrillic: "0425", - Kheicoptic: "03E6", - Khook: "0198", - Kjecyrillic: "040C", - Klinebelow: "1E34", - Kmonospace: "FF2B", - Koppacyrillic: "0480", - Koppagreek: "03DE", - Ksicyrillic: "046E", - Ksmall: "F76B", - L: "004C", - LJ: "01C7", - LL: "F6BF", - Lacute: "0139", - Lambda: "039B", - Lcaron: "013D", - Lcedilla: "013B", - Lcircle: "24C1", - Lcircumflexbelow: "1E3C", - Lcommaaccent: "013B", - Ldot: "013F", - Ldotaccent: "013F", - Ldotbelow: "1E36", - Ldotbelowmacron: "1E38", - Liwnarmenian: "053C", - Lj: "01C8", - Ljecyrillic: "0409", - Llinebelow: "1E3A", - Lmonospace: "FF2C", - Lslash: "0141", - Lslashsmall: "F6F9", - Lsmall: "F76C", - M: "004D", - MBsquare: "3386", - Macron: "F6D0", - Macronsmall: "F7AF", - Macute: "1E3E", - Mcircle: "24C2", - Mdotaccent: "1E40", - Mdotbelow: "1E42", - Menarmenian: "0544", - Mmonospace: "FF2D", - Msmall: "F76D", - Mturned: "019C", - Mu: "039C", - N: "004E", - NJ: "01CA", - Nacute: "0143", - Ncaron: "0147", - Ncedilla: "0145", - Ncircle: "24C3", - Ncircumflexbelow: "1E4A", - Ncommaaccent: "0145", - Ndotaccent: "1E44", - Ndotbelow: "1E46", - Nhookleft: "019D", - Nineroman: "2168", - Nj: "01CB", - Njecyrillic: "040A", - Nlinebelow: "1E48", - Nmonospace: "FF2E", - Nowarmenian: "0546", - Nsmall: "F76E", - Ntilde: "00D1", - Ntildesmall: "F7F1", - Nu: "039D", - O: "004F", - OE: "0152", - OEsmall: "F6FA", - Oacute: "00D3", - Oacutesmall: "F7F3", - Obarredcyrillic: "04E8", - Obarreddieresiscyrillic: "04EA", - Obreve: "014E", - Ocaron: "01D1", - Ocenteredtilde: "019F", - Ocircle: "24C4", - Ocircumflex: "00D4", - Ocircumflexacute: "1ED0", - Ocircumflexdotbelow: "1ED8", - Ocircumflexgrave: "1ED2", - Ocircumflexhookabove: "1ED4", - Ocircumflexsmall: "F7F4", - Ocircumflextilde: "1ED6", - Ocyrillic: "041E", - Odblacute: "0150", - Odblgrave: "020C", - Odieresis: "00D6", - Odieresiscyrillic: "04E6", - Odieresissmall: "F7F6", - Odotbelow: "1ECC", - Ogoneksmall: "F6FB", - Ograve: "00D2", - Ogravesmall: "F7F2", - Oharmenian: "0555", - Ohm: "2126", - Ohookabove: "1ECE", - Ohorn: "01A0", - Ohornacute: "1EDA", - Ohorndotbelow: "1EE2", - Ohorngrave: "1EDC", - Ohornhookabove: "1EDE", - Ohorntilde: "1EE0", - Ohungarumlaut: "0150", - Oi: "01A2", - Oinvertedbreve: "020E", - Omacron: "014C", - Omacronacute: "1E52", - Omacrongrave: "1E50", - Omega: "2126", - Omegacyrillic: "0460", - Omegagreek: "03A9", - Omegaroundcyrillic: "047A", - Omegatitlocyrillic: "047C", - Omegatonos: "038F", - Omicron: "039F", - Omicrontonos: "038C", - Omonospace: "FF2F", - Oneroman: "2160", - Oogonek: "01EA", - Oogonekmacron: "01EC", - Oopen: "0186", - Oslash: "00D8", - Oslashacute: "01FE", - Oslashsmall: "F7F8", - Osmall: "F76F", - Ostrokeacute: "01FE", - Otcyrillic: "047E", - Otilde: "00D5", - Otildeacute: "1E4C", - Otildedieresis: "1E4E", - Otildesmall: "F7F5", - P: "0050", - Pacute: "1E54", - Pcircle: "24C5", - Pdotaccent: "1E56", - Pecyrillic: "041F", - Peharmenian: "054A", - Pemiddlehookcyrillic: "04A6", - Phi: "03A6", - Phook: "01A4", - Pi: "03A0", - Piwrarmenian: "0553", - Pmonospace: "FF30", - Psi: "03A8", - Psicyrillic: "0470", - Psmall: "F770", - Q: "0051", - Qcircle: "24C6", - Qmonospace: "FF31", - Qsmall: "F771", - R: "0052", - Raarmenian: "054C", - Racute: "0154", - Rcaron: "0158", - Rcedilla: "0156", - Rcircle: "24C7", - Rcommaaccent: "0156", - Rdblgrave: "0210", - Rdotaccent: "1E58", - Rdotbelow: "1E5A", - Rdotbelowmacron: "1E5C", - Reharmenian: "0550", - Rfraktur: "211C", - Rho: "03A1", - Ringsmall: "F6FC", - Rinvertedbreve: "0212", - Rlinebelow: "1E5E", - Rmonospace: "FF32", - Rsmall: "F772", - Rsmallinverted: "0281", - Rsmallinvertedsuperior: "02B6", - S: "0053", - SF010000: "250C", - SF020000: "2514", - SF030000: "2510", - SF040000: "2518", - SF050000: "253C", - SF060000: "252C", - SF070000: "2534", - SF080000: "251C", - SF090000: "2524", - SF100000: "2500", - SF110000: "2502", - SF190000: "2561", - SF200000: "2562", - SF210000: "2556", - SF220000: "2555", - SF230000: "2563", - SF240000: "2551", - SF250000: "2557", - SF260000: "255D", - SF270000: "255C", - SF280000: "255B", - SF360000: "255E", - SF370000: "255F", - SF380000: "255A", - SF390000: "2554", - SF400000: "2569", - SF410000: "2566", - SF420000: "2560", - SF430000: "2550", - SF440000: "256C", - SF450000: "2567", - SF460000: "2568", - SF470000: "2564", - SF480000: "2565", - SF490000: "2559", - SF500000: "2558", - SF510000: "2552", - SF520000: "2553", - SF530000: "256B", - SF540000: "256A", - Sacute: "015A", - Sacutedotaccent: "1E64", - Sampigreek: "03E0", - Scaron: "0160", - Scarondotaccent: "1E66", - Scaronsmall: "F6FD", - Scedilla: "015E", - Schwa: "018F", - Schwacyrillic: "04D8", - Schwadieresiscyrillic: "04DA", - Scircle: "24C8", - Scircumflex: "015C", - Scommaaccent: "0218", - Sdotaccent: "1E60", - Sdotbelow: "1E62", - Sdotbelowdotaccent: "1E68", - Seharmenian: "054D", - Sevenroman: "2166", - Shaarmenian: "0547", - Shacyrillic: "0428", - Shchacyrillic: "0429", - Sheicoptic: "03E2", - Shhacyrillic: "04BA", - Shimacoptic: "03EC", - Sigma: "03A3", - Sixroman: "2165", - Smonospace: "FF33", - Softsigncyrillic: "042C", - Ssmall: "F773", - Stigmagreek: "03DA", - T: "0054", - Tau: "03A4", - Tbar: "0166", - Tcaron: "0164", - Tcedilla: "0162", - Tcircle: "24C9", - Tcircumflexbelow: "1E70", - Tcommaaccent: "0162", - Tdotaccent: "1E6A", - Tdotbelow: "1E6C", - Tecyrillic: "0422", - Tedescendercyrillic: "04AC", - Tenroman: "2169", - Tetsecyrillic: "04B4", - Theta: "0398", - Thook: "01AC", - Thorn: "00DE", - Thornsmall: "F7FE", - Threeroman: "2162", - Tildesmall: "F6FE", - Tiwnarmenian: "054F", - Tlinebelow: "1E6E", - Tmonospace: "FF34", - Toarmenian: "0539", - Tonefive: "01BC", - Tonesix: "0184", - Tonetwo: "01A7", - Tretroflexhook: "01AE", - Tsecyrillic: "0426", - Tshecyrillic: "040B", - Tsmall: "F774", - Twelveroman: "216B", - Tworoman: "2161", - U: "0055", - Uacute: "00DA", - Uacutesmall: "F7FA", - Ubreve: "016C", - Ucaron: "01D3", - Ucircle: "24CA", - Ucircumflex: "00DB", - Ucircumflexbelow: "1E76", - Ucircumflexsmall: "F7FB", - Ucyrillic: "0423", - Udblacute: "0170", - Udblgrave: "0214", - Udieresis: "00DC", - Udieresisacute: "01D7", - Udieresisbelow: "1E72", - Udieresiscaron: "01D9", - Udieresiscyrillic: "04F0", - Udieresisgrave: "01DB", - Udieresismacron: "01D5", - Udieresissmall: "F7FC", - Udotbelow: "1EE4", - Ugrave: "00D9", - Ugravesmall: "F7F9", - Uhookabove: "1EE6", - Uhorn: "01AF", - Uhornacute: "1EE8", - Uhorndotbelow: "1EF0", - Uhorngrave: "1EEA", - Uhornhookabove: "1EEC", - Uhorntilde: "1EEE", - Uhungarumlaut: "0170", - Uhungarumlautcyrillic: "04F2", - Uinvertedbreve: "0216", - Ukcyrillic: "0478", - Umacron: "016A", - Umacroncyrillic: "04EE", - Umacrondieresis: "1E7A", - Umonospace: "FF35", - Uogonek: "0172", - Upsilon: "03A5", - Upsilon1: "03D2", - Upsilonacutehooksymbolgreek: "03D3", - Upsilonafrican: "01B1", - Upsilondieresis: "03AB", - Upsilondieresishooksymbolgreek: "03D4", - Upsilonhooksymbol: "03D2", - Upsilontonos: "038E", - Uring: "016E", - Ushortcyrillic: "040E", - Usmall: "F775", - Ustraightcyrillic: "04AE", - Ustraightstrokecyrillic: "04B0", - Utilde: "0168", - Utildeacute: "1E78", - Utildebelow: "1E74", - V: "0056", - Vcircle: "24CB", - Vdotbelow: "1E7E", - Vecyrillic: "0412", - Vewarmenian: "054E", - Vhook: "01B2", - Vmonospace: "FF36", - Voarmenian: "0548", - Vsmall: "F776", - Vtilde: "1E7C", - W: "0057", - Wacute: "1E82", - Wcircle: "24CC", - Wcircumflex: "0174", - Wdieresis: "1E84", - Wdotaccent: "1E86", - Wdotbelow: "1E88", - Wgrave: "1E80", - Wmonospace: "FF37", - Wsmall: "F777", - X: "0058", - Xcircle: "24CD", - Xdieresis: "1E8C", - Xdotaccent: "1E8A", - Xeharmenian: "053D", - Xi: "039E", - Xmonospace: "FF38", - Xsmall: "F778", - Y: "0059", - Yacute: "00DD", - Yacutesmall: "F7FD", - Yatcyrillic: "0462", - Ycircle: "24CE", - Ycircumflex: "0176", - Ydieresis: "0178", - Ydieresissmall: "F7FF", - Ydotaccent: "1E8E", - Ydotbelow: "1EF4", - Yericyrillic: "042B", - Yerudieresiscyrillic: "04F8", - Ygrave: "1EF2", - Yhook: "01B3", - Yhookabove: "1EF6", - Yiarmenian: "0545", - Yicyrillic: "0407", - Yiwnarmenian: "0552", - Ymonospace: "FF39", - Ysmall: "F779", - Ytilde: "1EF8", - Yusbigcyrillic: "046A", - Yusbigiotifiedcyrillic: "046C", - Yuslittlecyrillic: "0466", - Yuslittleiotifiedcyrillic: "0468", - Z: "005A", - Zaarmenian: "0536", - Zacute: "0179", - Zcaron: "017D", - Zcaronsmall: "F6FF", - Zcircle: "24CF", - Zcircumflex: "1E90", - Zdot: "017B", - Zdotaccent: "017B", - Zdotbelow: "1E92", - Zecyrillic: "0417", - Zedescendercyrillic: "0498", - Zedieresiscyrillic: "04DE", - Zeta: "0396", - Zhearmenian: "053A", - Zhebrevecyrillic: "04C1", - Zhecyrillic: "0416", - Zhedescendercyrillic: "0496", - Zhedieresiscyrillic: "04DC", - Zlinebelow: "1E94", - Zmonospace: "FF3A", - Zsmall: "F77A", - Zstroke: "01B5", - a: "0061", - aabengali: "0986", - aacute: "00E1", - aadeva: "0906", - aagujarati: "0A86", - aagurmukhi: "0A06", - aamatragurmukhi: "0A3E", - aarusquare: "3303", - aavowelsignbengali: "09BE", - aavowelsigndeva: "093E", - aavowelsigngujarati: "0ABE", - abbreviationmarkarmenian: "055F", - abbreviationsigndeva: "0970", - abengali: "0985", - abopomofo: "311A", - abreve: "0103", - abreveacute: "1EAF", - abrevecyrillic: "04D1", - abrevedotbelow: "1EB7", - abrevegrave: "1EB1", - abrevehookabove: "1EB3", - abrevetilde: "1EB5", - acaron: "01CE", - acircle: "24D0", - acircumflex: "00E2", - acircumflexacute: "1EA5", - acircumflexdotbelow: "1EAD", - acircumflexgrave: "1EA7", - acircumflexhookabove: "1EA9", - acircumflextilde: "1EAB", - acute: "00B4", - acutebelowcmb: "0317", - acutecmb: "0301", - acutecomb: "0301", - acutedeva: "0954", - acutelowmod: "02CF", - acutetonecmb: "0341", - acyrillic: "0430", - adblgrave: "0201", - addakgurmukhi: "0A71", - adeva: "0905", - adieresis: "00E4", - adieresiscyrillic: "04D3", - adieresismacron: "01DF", - adotbelow: "1EA1", - adotmacron: "01E1", - ae: "00E6", - aeacute: "01FD", - aekorean: "3150", - aemacron: "01E3", - afii00208: "2015", - afii08941: "20A4", - afii10017: "0410", - afii10018: "0411", - afii10019: "0412", - afii10020: "0413", - afii10021: "0414", - afii10022: "0415", - afii10023: "0401", - afii10024: "0416", - afii10025: "0417", - afii10026: "0418", - afii10027: "0419", - afii10028: "041A", - afii10029: "041B", - afii10030: "041C", - afii10031: "041D", - afii10032: "041E", - afii10033: "041F", - afii10034: "0420", - afii10035: "0421", - afii10036: "0422", - afii10037: "0423", - afii10038: "0424", - afii10039: "0425", - afii10040: "0426", - afii10041: "0427", - afii10042: "0428", - afii10043: "0429", - afii10044: "042A", - afii10045: "042B", - afii10046: "042C", - afii10047: "042D", - afii10048: "042E", - afii10049: "042F", - afii10050: "0490", - afii10051: "0402", - afii10052: "0403", - afii10053: "0404", - afii10054: "0405", - afii10055: "0406", - afii10056: "0407", - afii10057: "0408", - afii10058: "0409", - afii10059: "040A", - afii10060: "040B", - afii10061: "040C", - afii10062: "040E", - afii10063: "F6C4", - afii10064: "F6C5", - afii10065: "0430", - afii10066: "0431", - afii10067: "0432", - afii10068: "0433", - afii10069: "0434", - afii10070: "0435", - afii10071: "0451", - afii10072: "0436", - afii10073: "0437", - afii10074: "0438", - afii10075: "0439", - afii10076: "043A", - afii10077: "043B", - afii10078: "043C", - afii10079: "043D", - afii10080: "043E", - afii10081: "043F", - afii10082: "0440", - afii10083: "0441", - afii10084: "0442", - afii10085: "0443", - afii10086: "0444", - afii10087: "0445", - afii10088: "0446", - afii10089: "0447", - afii10090: "0448", - afii10091: "0449", - afii10092: "044A", - afii10093: "044B", - afii10094: "044C", - afii10095: "044D", - afii10096: "044E", - afii10097: "044F", - afii10098: "0491", - afii10099: "0452", - afii10100: "0453", - afii10101: "0454", - afii10102: "0455", - afii10103: "0456", - afii10104: "0457", - afii10105: "0458", - afii10106: "0459", - afii10107: "045A", - afii10108: "045B", - afii10109: "045C", - afii10110: "045E", - afii10145: "040F", - afii10146: "0462", - afii10147: "0472", - afii10148: "0474", - afii10192: "F6C6", - afii10193: "045F", - afii10194: "0463", - afii10195: "0473", - afii10196: "0475", - afii10831: "F6C7", - afii10832: "F6C8", - afii10846: "04D9", - afii299: "200E", - afii300: "200F", - afii301: "200D", - afii57381: "066A", - afii57388: "060C", - afii57392: "0660", - afii57393: "0661", - afii57394: "0662", - afii57395: "0663", - afii57396: "0664", - afii57397: "0665", - afii57398: "0666", - afii57399: "0667", - afii57400: "0668", - afii57401: "0669", - afii57403: "061B", - afii57407: "061F", - afii57409: "0621", - afii57410: "0622", - afii57411: "0623", - afii57412: "0624", - afii57413: "0625", - afii57414: "0626", - afii57415: "0627", - afii57416: "0628", - afii57417: "0629", - afii57418: "062A", - afii57419: "062B", - afii57420: "062C", - afii57421: "062D", - afii57422: "062E", - afii57423: "062F", - afii57424: "0630", - afii57425: "0631", - afii57426: "0632", - afii57427: "0633", - afii57428: "0634", - afii57429: "0635", - afii57430: "0636", - afii57431: "0637", - afii57432: "0638", - afii57433: "0639", - afii57434: "063A", - afii57440: "0640", - afii57441: "0641", - afii57442: "0642", - afii57443: "0643", - afii57444: "0644", - afii57445: "0645", - afii57446: "0646", - afii57448: "0648", - afii57449: "0649", - afii57450: "064A", - afii57451: "064B", - afii57452: "064C", - afii57453: "064D", - afii57454: "064E", - afii57455: "064F", - afii57456: "0650", - afii57457: "0651", - afii57458: "0652", - afii57470: "0647", - afii57505: "06A4", - afii57506: "067E", - afii57507: "0686", - afii57508: "0698", - afii57509: "06AF", - afii57511: "0679", - afii57512: "0688", - afii57513: "0691", - afii57514: "06BA", - afii57519: "06D2", - afii57534: "06D5", - afii57636: "20AA", - afii57645: "05BE", - afii57658: "05C3", - afii57664: "05D0", - afii57665: "05D1", - afii57666: "05D2", - afii57667: "05D3", - afii57668: "05D4", - afii57669: "05D5", - afii57670: "05D6", - afii57671: "05D7", - afii57672: "05D8", - afii57673: "05D9", - afii57674: "05DA", - afii57675: "05DB", - afii57676: "05DC", - afii57677: "05DD", - afii57678: "05DE", - afii57679: "05DF", - afii57680: "05E0", - afii57681: "05E1", - afii57682: "05E2", - afii57683: "05E3", - afii57684: "05E4", - afii57685: "05E5", - afii57686: "05E6", - afii57687: "05E7", - afii57688: "05E8", - afii57689: "05E9", - afii57690: "05EA", - afii57694: "FB2A", - afii57695: "FB2B", - afii57700: "FB4B", - afii57705: "FB1F", - afii57716: "05F0", - afii57717: "05F1", - afii57718: "05F2", - afii57723: "FB35", - afii57793: "05B4", - afii57794: "05B5", - afii57795: "05B6", - afii57796: "05BB", - afii57797: "05B8", - afii57798: "05B7", - afii57799: "05B0", - afii57800: "05B2", - afii57801: "05B1", - afii57802: "05B3", - afii57803: "05C2", - afii57804: "05C1", - afii57806: "05B9", - afii57807: "05BC", - afii57839: "05BD", - afii57841: "05BF", - afii57842: "05C0", - afii57929: "02BC", - afii61248: "2105", - afii61289: "2113", - afii61352: "2116", - afii61573: "202C", - afii61574: "202D", - afii61575: "202E", - afii61664: "200C", - afii63167: "066D", - afii64937: "02BD", - agrave: "00E0", - agujarati: "0A85", - agurmukhi: "0A05", - ahiragana: "3042", - ahookabove: "1EA3", - aibengali: "0990", - aibopomofo: "311E", - aideva: "0910", - aiecyrillic: "04D5", - aigujarati: "0A90", - aigurmukhi: "0A10", - aimatragurmukhi: "0A48", - ainarabic: "0639", - ainfinalarabic: "FECA", - aininitialarabic: "FECB", - ainmedialarabic: "FECC", - ainvertedbreve: "0203", - aivowelsignbengali: "09C8", - aivowelsigndeva: "0948", - aivowelsigngujarati: "0AC8", - akatakana: "30A2", - akatakanahalfwidth: "FF71", - akorean: "314F", - alef: "05D0", - alefarabic: "0627", - alefdageshhebrew: "FB30", - aleffinalarabic: "FE8E", - alefhamzaabovearabic: "0623", - alefhamzaabovefinalarabic: "FE84", - alefhamzabelowarabic: "0625", - alefhamzabelowfinalarabic: "FE88", - alefhebrew: "05D0", - aleflamedhebrew: "FB4F", - alefmaddaabovearabic: "0622", - alefmaddaabovefinalarabic: "FE82", - alefmaksuraarabic: "0649", - alefmaksurafinalarabic: "FEF0", - alefmaksurainitialarabic: "FEF3", - alefmaksuramedialarabic: "FEF4", - alefpatahhebrew: "FB2E", - alefqamatshebrew: "FB2F", - aleph: "2135", - allequal: "224C", - alpha: "03B1", - alphatonos: "03AC", - amacron: "0101", - amonospace: "FF41", - ampersand: "0026", - ampersandmonospace: "FF06", - ampersandsmall: "F726", - amsquare: "33C2", - anbopomofo: "3122", - angbopomofo: "3124", - angkhankhuthai: "0E5A", - angle: "2220", - anglebracketleft: "3008", - anglebracketleftvertical: "FE3F", - anglebracketright: "3009", - anglebracketrightvertical: "FE40", - angleleft: "2329", - angleright: "232A", - angstrom: "212B", - anoteleia: "0387", - anudattadeva: "0952", - anusvarabengali: "0982", - anusvaradeva: "0902", - anusvaragujarati: "0A82", - aogonek: "0105", - apaatosquare: "3300", - aparen: "249C", - apostrophearmenian: "055A", - apostrophemod: "02BC", - apple: "F8FF", - approaches: "2250", - approxequal: "2248", - approxequalorimage: "2252", - approximatelyequal: "2245", - araeaekorean: "318E", - araeakorean: "318D", - arc: "2312", - arighthalfring: "1E9A", - aring: "00E5", - aringacute: "01FB", - aringbelow: "1E01", - arrowboth: "2194", - arrowdashdown: "21E3", - arrowdashleft: "21E0", - arrowdashright: "21E2", - arrowdashup: "21E1", - arrowdblboth: "21D4", - arrowdbldown: "21D3", - arrowdblleft: "21D0", - arrowdblright: "21D2", - arrowdblup: "21D1", - arrowdown: "2193", - arrowdownleft: "2199", - arrowdownright: "2198", - arrowdownwhite: "21E9", - arrowheaddownmod: "02C5", - arrowheadleftmod: "02C2", - arrowheadrightmod: "02C3", - arrowheadupmod: "02C4", - arrowhorizex: "F8E7", - arrowleft: "2190", - arrowleftdbl: "21D0", - arrowleftdblstroke: "21CD", - arrowleftoverright: "21C6", - arrowleftwhite: "21E6", - arrowright: "2192", - arrowrightdblstroke: "21CF", - arrowrightheavy: "279E", - arrowrightoverleft: "21C4", - arrowrightwhite: "21E8", - arrowtableft: "21E4", - arrowtabright: "21E5", - arrowup: "2191", - arrowupdn: "2195", - arrowupdnbse: "21A8", - arrowupdownbase: "21A8", - arrowupleft: "2196", - arrowupleftofdown: "21C5", - arrowupright: "2197", - arrowupwhite: "21E7", - arrowvertex: "F8E6", - asciicircum: "005E", - asciicircummonospace: "FF3E", - asciitilde: "007E", - asciitildemonospace: "FF5E", - ascript: "0251", - ascriptturned: "0252", - asmallhiragana: "3041", - asmallkatakana: "30A1", - asmallkatakanahalfwidth: "FF67", - asterisk: "002A", - asteriskaltonearabic: "066D", - asteriskarabic: "066D", - asteriskmath: "2217", - asteriskmonospace: "FF0A", - asterisksmall: "FE61", - asterism: "2042", - asuperior: "F6E9", - asymptoticallyequal: "2243", - at: "0040", - atilde: "00E3", - atmonospace: "FF20", - atsmall: "FE6B", - aturned: "0250", - aubengali: "0994", - aubopomofo: "3120", - audeva: "0914", - augujarati: "0A94", - augurmukhi: "0A14", - aulengthmarkbengali: "09D7", - aumatragurmukhi: "0A4C", - auvowelsignbengali: "09CC", - auvowelsigndeva: "094C", - auvowelsigngujarati: "0ACC", - avagrahadeva: "093D", - aybarmenian: "0561", - ayin: "05E2", - ayinaltonehebrew: "FB20", - ayinhebrew: "05E2", - b: "0062", - babengali: "09AC", - backslash: "005C", - backslashmonospace: "FF3C", - badeva: "092C", - bagujarati: "0AAC", - bagurmukhi: "0A2C", - bahiragana: "3070", - bahtthai: "0E3F", - bakatakana: "30D0", - bar: "007C", - barmonospace: "FF5C", - bbopomofo: "3105", - bcircle: "24D1", - bdotaccent: "1E03", - bdotbelow: "1E05", - beamedsixteenthnotes: "266C", - because: "2235", - becyrillic: "0431", - beharabic: "0628", - behfinalarabic: "FE90", - behinitialarabic: "FE91", - behiragana: "3079", - behmedialarabic: "FE92", - behmeeminitialarabic: "FC9F", - behmeemisolatedarabic: "FC08", - behnoonfinalarabic: "FC6D", - bekatakana: "30D9", - benarmenian: "0562", - bet: "05D1", - beta: "03B2", - betasymbolgreek: "03D0", - betdagesh: "FB31", - betdageshhebrew: "FB31", - bethebrew: "05D1", - betrafehebrew: "FB4C", - bhabengali: "09AD", - bhadeva: "092D", - bhagujarati: "0AAD", - bhagurmukhi: "0A2D", - bhook: "0253", - bihiragana: "3073", - bikatakana: "30D3", - bilabialclick: "0298", - bindigurmukhi: "0A02", - birusquare: "3331", - blackcircle: "25CF", - blackdiamond: "25C6", - blackdownpointingtriangle: "25BC", - blackleftpointingpointer: "25C4", - blackleftpointingtriangle: "25C0", - blacklenticularbracketleft: "3010", - blacklenticularbracketleftvertical: "FE3B", - blacklenticularbracketright: "3011", - blacklenticularbracketrightvertical: "FE3C", - blacklowerlefttriangle: "25E3", - blacklowerrighttriangle: "25E2", - blackrectangle: "25AC", - blackrightpointingpointer: "25BA", - blackrightpointingtriangle: "25B6", - blacksmallsquare: "25AA", - blacksmilingface: "263B", - blacksquare: "25A0", - blackstar: "2605", - blackupperlefttriangle: "25E4", - blackupperrighttriangle: "25E5", - blackuppointingsmalltriangle: "25B4", - blackuppointingtriangle: "25B2", - blank: "2423", - blinebelow: "1E07", - block: "2588", - bmonospace: "FF42", - bobaimaithai: "0E1A", - bohiragana: "307C", - bokatakana: "30DC", - bparen: "249D", - bqsquare: "33C3", - braceex: "F8F4", - braceleft: "007B", - braceleftbt: "F8F3", - braceleftmid: "F8F2", - braceleftmonospace: "FF5B", - braceleftsmall: "FE5B", - bracelefttp: "F8F1", - braceleftvertical: "FE37", - braceright: "007D", - bracerightbt: "F8FE", - bracerightmid: "F8FD", - bracerightmonospace: "FF5D", - bracerightsmall: "FE5C", - bracerighttp: "F8FC", - bracerightvertical: "FE38", - bracketleft: "005B", - bracketleftbt: "F8F0", - bracketleftex: "F8EF", - bracketleftmonospace: "FF3B", - bracketlefttp: "F8EE", - bracketright: "005D", - bracketrightbt: "F8FB", - bracketrightex: "F8FA", - bracketrightmonospace: "FF3D", - bracketrighttp: "F8F9", - breve: "02D8", - brevebelowcmb: "032E", - brevecmb: "0306", - breveinvertedbelowcmb: "032F", - breveinvertedcmb: "0311", - breveinverteddoublecmb: "0361", - bridgebelowcmb: "032A", - bridgeinvertedbelowcmb: "033A", - brokenbar: "00A6", - bstroke: "0180", - bsuperior: "F6EA", - btopbar: "0183", - buhiragana: "3076", - bukatakana: "30D6", - bullet: "2022", - bulletinverse: "25D8", - bulletoperator: "2219", - bullseye: "25CE", - c: "0063", - caarmenian: "056E", - cabengali: "099A", - cacute: "0107", - cadeva: "091A", - cagujarati: "0A9A", - cagurmukhi: "0A1A", - calsquare: "3388", - candrabindubengali: "0981", - candrabinducmb: "0310", - candrabindudeva: "0901", - candrabindugujarati: "0A81", - capslock: "21EA", - careof: "2105", - caron: "02C7", - caronbelowcmb: "032C", - caroncmb: "030C", - carriagereturn: "21B5", - cbopomofo: "3118", - ccaron: "010D", - ccedilla: "00E7", - ccedillaacute: "1E09", - ccircle: "24D2", - ccircumflex: "0109", - ccurl: "0255", - cdot: "010B", - cdotaccent: "010B", - cdsquare: "33C5", - cedilla: "00B8", - cedillacmb: "0327", - cent: "00A2", - centigrade: "2103", - centinferior: "F6DF", - centmonospace: "FFE0", - centoldstyle: "F7A2", - centsuperior: "F6E0", - chaarmenian: "0579", - chabengali: "099B", - chadeva: "091B", - chagujarati: "0A9B", - chagurmukhi: "0A1B", - chbopomofo: "3114", - cheabkhasiancyrillic: "04BD", - checkmark: "2713", - checyrillic: "0447", - chedescenderabkhasiancyrillic: "04BF", - chedescendercyrillic: "04B7", - chedieresiscyrillic: "04F5", - cheharmenian: "0573", - chekhakassiancyrillic: "04CC", - cheverticalstrokecyrillic: "04B9", - chi: "03C7", - chieuchacirclekorean: "3277", - chieuchaparenkorean: "3217", - chieuchcirclekorean: "3269", - chieuchkorean: "314A", - chieuchparenkorean: "3209", - chochangthai: "0E0A", - chochanthai: "0E08", - chochingthai: "0E09", - chochoethai: "0E0C", - chook: "0188", - cieucacirclekorean: "3276", - cieucaparenkorean: "3216", - cieuccirclekorean: "3268", - cieuckorean: "3148", - cieucparenkorean: "3208", - cieucuparenkorean: "321C", - circle: "25CB", - circlemultiply: "2297", - circleot: "2299", - circleplus: "2295", - circlepostalmark: "3036", - circlewithlefthalfblack: "25D0", - circlewithrighthalfblack: "25D1", - circumflex: "02C6", - circumflexbelowcmb: "032D", - circumflexcmb: "0302", - clear: "2327", - clickalveolar: "01C2", - clickdental: "01C0", - clicklateral: "01C1", - clickretroflex: "01C3", - club: "2663", - clubsuitblack: "2663", - clubsuitwhite: "2667", - cmcubedsquare: "33A4", - cmonospace: "FF43", - cmsquaredsquare: "33A0", - coarmenian: "0581", - colon: "003A", - colonmonetary: "20A1", - colonmonospace: "FF1A", - colonsign: "20A1", - colonsmall: "FE55", - colontriangularhalfmod: "02D1", - colontriangularmod: "02D0", - comma: "002C", - commaabovecmb: "0313", - commaaboverightcmb: "0315", - commaaccent: "F6C3", - commaarabic: "060C", - commaarmenian: "055D", - commainferior: "F6E1", - commamonospace: "FF0C", - commareversedabovecmb: "0314", - commareversedmod: "02BD", - commasmall: "FE50", - commasuperior: "F6E2", - commaturnedabovecmb: "0312", - commaturnedmod: "02BB", - compass: "263C", - congruent: "2245", - contourintegral: "222E", - control: "2303", - controlACK: "0006", - controlBEL: "0007", - controlBS: "0008", - controlCAN: "0018", - controlCR: "000D", - controlDC1: "0011", - controlDC2: "0012", - controlDC3: "0013", - controlDC4: "0014", - controlDEL: "007F", - controlDLE: "0010", - controlEM: "0019", - controlENQ: "0005", - controlEOT: "0004", - controlESC: "001B", - controlETB: "0017", - controlETX: "0003", - controlFF: "000C", - controlFS: "001C", - controlGS: "001D", - controlHT: "0009", - controlLF: "000A", - controlNAK: "0015", - controlRS: "001E", - controlSI: "000F", - controlSO: "000E", - controlSOT: "0002", - controlSTX: "0001", - controlSUB: "001A", - controlSYN: "0016", - controlUS: "001F", - controlVT: "000B", - copyright: "00A9", - copyrightsans: "F8E9", - copyrightserif: "F6D9", - cornerbracketleft: "300C", - cornerbracketlefthalfwidth: "FF62", - cornerbracketleftvertical: "FE41", - cornerbracketright: "300D", - cornerbracketrighthalfwidth: "FF63", - cornerbracketrightvertical: "FE42", - corporationsquare: "337F", - cosquare: "33C7", - coverkgsquare: "33C6", - cparen: "249E", - cruzeiro: "20A2", - cstretched: "0297", - curlyand: "22CF", - curlyor: "22CE", - currency: "00A4", - cyrBreve: "F6D1", - cyrFlex: "F6D2", - cyrbreve: "F6D4", - cyrflex: "F6D5", - d: "0064", - daarmenian: "0564", - dabengali: "09A6", - dadarabic: "0636", - dadeva: "0926", - dadfinalarabic: "FEBE", - dadinitialarabic: "FEBF", - dadmedialarabic: "FEC0", - dagesh: "05BC", - dageshhebrew: "05BC", - dagger: "2020", - daggerdbl: "2021", - dagujarati: "0AA6", - dagurmukhi: "0A26", - dahiragana: "3060", - dakatakana: "30C0", - dalarabic: "062F", - dalet: "05D3", - daletdagesh: "FB33", - daletdageshhebrew: "FB33", + 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: "05D3", + dalethebrew: 0x05D3, dalethiriq: "05D3 05B4", dalethiriqhebrew: "05D3 05B4", daletholam: "05D3 05B9", @@ -1521,1641 +1521,1641 @@ var GlyphsUnicode = { daletshevahebrew: "05D3 05B0", dalettsere: "05D3 05B5", dalettserehebrew: "05D3 05B5", - dalfinalarabic: "FEAA", - dammaarabic: "064F", - dammalowarabic: "064F", - dammatanaltonearabic: "064C", - dammatanarabic: "064C", - danda: "0964", - dargahebrew: "05A7", - dargalefthebrew: "05A7", - dasiapneumatacyrilliccmb: "0485", - dblGrave: "F6D3", - dblanglebracketleft: "300A", - dblanglebracketleftvertical: "FE3D", - dblanglebracketright: "300B", - dblanglebracketrightvertical: "FE3E", - dblarchinvertedbelowcmb: "032B", - dblarrowleft: "21D4", - dblarrowright: "21D2", - dbldanda: "0965", - dblgrave: "F6D6", - dblgravecmb: "030F", - dblintegral: "222C", - dbllowline: "2017", - dbllowlinecmb: "0333", - dbloverlinecmb: "033F", - dblprimemod: "02BA", - dblverticalbar: "2016", - dblverticallineabovecmb: "030E", - dbopomofo: "3109", - dbsquare: "33C8", - dcaron: "010F", - dcedilla: "1E11", - dcircle: "24D3", - dcircumflexbelow: "1E13", - dcroat: "0111", - ddabengali: "09A1", - ddadeva: "0921", - ddagujarati: "0AA1", - ddagurmukhi: "0A21", - ddalarabic: "0688", - ddalfinalarabic: "FB89", - dddhadeva: "095C", - ddhabengali: "09A2", - ddhadeva: "0922", - ddhagujarati: "0AA2", - ddhagurmukhi: "0A22", - ddotaccent: "1E0B", - ddotbelow: "1E0D", - decimalseparatorarabic: "066B", - decimalseparatorpersian: "066B", - decyrillic: "0434", - degree: "00B0", - dehihebrew: "05AD", - dehiragana: "3067", - deicoptic: "03EF", - dekatakana: "30C7", - deleteleft: "232B", - deleteright: "2326", - delta: "03B4", - deltaturned: "018D", - denominatorminusonenumeratorbengali: "09F8", - dezh: "02A4", - dhabengali: "09A7", - dhadeva: "0927", - dhagujarati: "0AA7", - dhagurmukhi: "0A27", - dhook: "0257", - dialytikatonos: "0385", - dialytikatonoscmb: "0344", - diamond: "2666", - diamondsuitwhite: "2662", - dieresis: "00A8", - dieresisacute: "F6D7", - dieresisbelowcmb: "0324", - dieresiscmb: "0308", - dieresisgrave: "F6D8", - dieresistonos: "0385", - dihiragana: "3062", - dikatakana: "30C2", - dittomark: "3003", - divide: "00F7", - divides: "2223", - divisionslash: "2215", - djecyrillic: "0452", - dkshade: "2593", - dlinebelow: "1E0F", - dlsquare: "3397", - dmacron: "0111", - dmonospace: "FF44", - dnblock: "2584", - dochadathai: "0E0E", - dodekthai: "0E14", - dohiragana: "3069", - dokatakana: "30C9", - dollar: "0024", - dollarinferior: "F6E3", - dollarmonospace: "FF04", - dollaroldstyle: "F724", - dollarsmall: "FE69", - dollarsuperior: "F6E4", - dong: "20AB", - dorusquare: "3326", - dotaccent: "02D9", - dotaccentcmb: "0307", - dotbelowcmb: "0323", - dotbelowcomb: "0323", - dotkatakana: "30FB", - dotlessi: "0131", - dotlessj: "F6BE", - dotlessjstrokehook: "0284", - dotmath: "22C5", - dottedcircle: "25CC", - doubleyodpatah: "FB1F", - doubleyodpatahhebrew: "FB1F", - downtackbelowcmb: "031E", - downtackmod: "02D5", - dparen: "249F", - dsuperior: "F6EB", - dtail: "0256", - dtopbar: "018C", - duhiragana: "3065", - dukatakana: "30C5", - dz: "01F3", - dzaltone: "02A3", - dzcaron: "01C6", - dzcurl: "02A5", - dzeabkhasiancyrillic: "04E1", - dzecyrillic: "0455", - dzhecyrillic: "045F", - e: "0065", - eacute: "00E9", - earth: "2641", - ebengali: "098F", - ebopomofo: "311C", - ebreve: "0115", - ecandradeva: "090D", - ecandragujarati: "0A8D", - ecandravowelsigndeva: "0945", - ecandravowelsigngujarati: "0AC5", - ecaron: "011B", - ecedillabreve: "1E1D", - echarmenian: "0565", - echyiwnarmenian: "0587", - ecircle: "24D4", - ecircumflex: "00EA", - ecircumflexacute: "1EBF", - ecircumflexbelow: "1E19", - ecircumflexdotbelow: "1EC7", - ecircumflexgrave: "1EC1", - ecircumflexhookabove: "1EC3", - ecircumflextilde: "1EC5", - ecyrillic: "0454", - edblgrave: "0205", - edeva: "090F", - edieresis: "00EB", - edot: "0117", - edotaccent: "0117", - edotbelow: "1EB9", - eegurmukhi: "0A0F", - eematragurmukhi: "0A47", - efcyrillic: "0444", - egrave: "00E8", - egujarati: "0A8F", - eharmenian: "0567", - ehbopomofo: "311D", - ehiragana: "3048", - ehookabove: "1EBB", - eibopomofo: "311F", - eight: "0038", - eightarabic: "0668", - eightbengali: "09EE", - eightcircle: "2467", - eightcircleinversesansserif: "2791", - eightdeva: "096E", - eighteencircle: "2471", - eighteenparen: "2485", - eighteenperiod: "2499", - eightgujarati: "0AEE", - eightgurmukhi: "0A6E", - eighthackarabic: "0668", - eighthangzhou: "3028", - eighthnotebeamed: "266B", - eightideographicparen: "3227", - eightinferior: "2088", - eightmonospace: "FF18", - eightoldstyle: "F738", - eightparen: "247B", - eightperiod: "248F", - eightpersian: "06F8", - eightroman: "2177", - eightsuperior: "2078", - eightthai: "0E58", - einvertedbreve: "0207", - eiotifiedcyrillic: "0465", - ekatakana: "30A8", - ekatakanahalfwidth: "FF74", - ekonkargurmukhi: "0A74", - ekorean: "3154", - elcyrillic: "043B", - element: "2208", - elevencircle: "246A", - elevenparen: "247E", - elevenperiod: "2492", - elevenroman: "217A", - ellipsis: "2026", - ellipsisvertical: "22EE", - emacron: "0113", - emacronacute: "1E17", - emacrongrave: "1E15", - emcyrillic: "043C", - emdash: "2014", - emdashvertical: "FE31", - emonospace: "FF45", - emphasismarkarmenian: "055B", - emptyset: "2205", - enbopomofo: "3123", - encyrillic: "043D", - endash: "2013", - endashvertical: "FE32", - endescendercyrillic: "04A3", - eng: "014B", - engbopomofo: "3125", - enghecyrillic: "04A5", - enhookcyrillic: "04C8", - enspace: "2002", - eogonek: "0119", - eokorean: "3153", - eopen: "025B", - eopenclosed: "029A", - eopenreversed: "025C", - eopenreversedclosed: "025E", - eopenreversedhook: "025D", - eparen: "24A0", - epsilon: "03B5", - epsilontonos: "03AD", - equal: "003D", - equalmonospace: "FF1D", - equalsmall: "FE66", - equalsuperior: "207C", - equivalence: "2261", - erbopomofo: "3126", - ercyrillic: "0440", - ereversed: "0258", - ereversedcyrillic: "044D", - escyrillic: "0441", - esdescendercyrillic: "04AB", - esh: "0283", - eshcurl: "0286", - eshortdeva: "090E", - eshortvowelsigndeva: "0946", - eshreversedloop: "01AA", - eshsquatreversed: "0285", - esmallhiragana: "3047", - esmallkatakana: "30A7", - esmallkatakanahalfwidth: "FF6A", - estimated: "212E", - esuperior: "F6EC", - eta: "03B7", - etarmenian: "0568", - etatonos: "03AE", - eth: "00F0", - etilde: "1EBD", - etildebelow: "1E1B", - etnahtafoukhhebrew: "0591", - etnahtafoukhlefthebrew: "0591", - etnahtahebrew: "0591", - etnahtalefthebrew: "0591", - eturned: "01DD", - eukorean: "3161", - euro: "20AC", - evowelsignbengali: "09C7", - evowelsigndeva: "0947", - evowelsigngujarati: "0AC7", - exclam: "0021", - exclamarmenian: "055C", - exclamdbl: "203C", - exclamdown: "00A1", - exclamdownsmall: "F7A1", - exclammonospace: "FF01", - exclamsmall: "F721", - existential: "2203", - ezh: "0292", - ezhcaron: "01EF", - ezhcurl: "0293", - ezhreversed: "01B9", - ezhtail: "01BA", - f: "0066", - fadeva: "095E", - fagurmukhi: "0A5E", - fahrenheit: "2109", - fathaarabic: "064E", - fathalowarabic: "064E", - fathatanarabic: "064B", - fbopomofo: "3108", - fcircle: "24D5", - fdotaccent: "1E1F", - feharabic: "0641", - feharmenian: "0586", - fehfinalarabic: "FED2", - fehinitialarabic: "FED3", - fehmedialarabic: "FED4", - feicoptic: "03E5", - female: "2640", - ff: "FB00", - ffi: "FB03", - ffl: "FB04", - fi: "FB01", - fifteencircle: "246E", - fifteenparen: "2482", - fifteenperiod: "2496", - figuredash: "2012", - filledbox: "25A0", - filledrect: "25AC", - finalkaf: "05DA", - finalkafdagesh: "FB3A", - finalkafdageshhebrew: "FB3A", - finalkafhebrew: "05DA", + 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: "05DD", - finalmemhebrew: "05DD", - finalnun: "05DF", - finalnunhebrew: "05DF", - finalpe: "05E3", - finalpehebrew: "05E3", - finaltsadi: "05E5", - finaltsadihebrew: "05E5", - firsttonechinese: "02C9", - fisheye: "25C9", - fitacyrillic: "0473", - five: "0035", - fivearabic: "0665", - fivebengali: "09EB", - fivecircle: "2464", - fivecircleinversesansserif: "278E", - fivedeva: "096B", - fiveeighths: "215D", - fivegujarati: "0AEB", - fivegurmukhi: "0A6B", - fivehackarabic: "0665", - fivehangzhou: "3025", - fiveideographicparen: "3224", - fiveinferior: "2085", - fivemonospace: "FF15", - fiveoldstyle: "F735", - fiveparen: "2478", - fiveperiod: "248C", - fivepersian: "06F5", - fiveroman: "2174", - fivesuperior: "2075", - fivethai: "0E55", - fl: "FB02", - florin: "0192", - fmonospace: "FF46", - fmsquare: "3399", - fofanthai: "0E1F", - fofathai: "0E1D", - fongmanthai: "0E4F", - forall: "2200", - four: "0034", - fourarabic: "0664", - fourbengali: "09EA", - fourcircle: "2463", - fourcircleinversesansserif: "278D", - fourdeva: "096A", - fourgujarati: "0AEA", - fourgurmukhi: "0A6A", - fourhackarabic: "0664", - fourhangzhou: "3024", - fourideographicparen: "3223", - fourinferior: "2084", - fourmonospace: "FF14", - fournumeratorbengali: "09F7", - fouroldstyle: "F734", - fourparen: "2477", - fourperiod: "248B", - fourpersian: "06F4", - fourroman: "2173", - foursuperior: "2074", - fourteencircle: "246D", - fourteenparen: "2481", - fourteenperiod: "2495", - fourthai: "0E54", - fourthtonechinese: "02CB", - fparen: "24A1", - fraction: "2044", - franc: "20A3", - g: "0067", - gabengali: "0997", - gacute: "01F5", - gadeva: "0917", - gafarabic: "06AF", - gaffinalarabic: "FB93", - gafinitialarabic: "FB94", - gafmedialarabic: "FB95", - gagujarati: "0A97", - gagurmukhi: "0A17", - gahiragana: "304C", - gakatakana: "30AC", - gamma: "03B3", - gammalatinsmall: "0263", - gammasuperior: "02E0", - gangiacoptic: "03EB", - gbopomofo: "310D", - gbreve: "011F", - gcaron: "01E7", - gcedilla: "0123", - gcircle: "24D6", - gcircumflex: "011D", - gcommaaccent: "0123", - gdot: "0121", - gdotaccent: "0121", - gecyrillic: "0433", - gehiragana: "3052", - gekatakana: "30B2", - geometricallyequal: "2251", - gereshaccenthebrew: "059C", - gereshhebrew: "05F3", - gereshmuqdamhebrew: "059D", - germandbls: "00DF", - gershayimaccenthebrew: "059E", - gershayimhebrew: "05F4", - getamark: "3013", - ghabengali: "0998", - ghadarmenian: "0572", - ghadeva: "0918", - ghagujarati: "0A98", - ghagurmukhi: "0A18", - ghainarabic: "063A", - ghainfinalarabic: "FECE", - ghaininitialarabic: "FECF", - ghainmedialarabic: "FED0", - ghemiddlehookcyrillic: "0495", - ghestrokecyrillic: "0493", - gheupturncyrillic: "0491", - ghhadeva: "095A", - ghhagurmukhi: "0A5A", - ghook: "0260", - ghzsquare: "3393", - gihiragana: "304E", - gikatakana: "30AE", - gimarmenian: "0563", - gimel: "05D2", - gimeldagesh: "FB32", - gimeldageshhebrew: "FB32", - gimelhebrew: "05D2", - gjecyrillic: "0453", - glottalinvertedstroke: "01BE", - glottalstop: "0294", - glottalstopinverted: "0296", - glottalstopmod: "02C0", - glottalstopreversed: "0295", - glottalstopreversedmod: "02C1", - glottalstopreversedsuperior: "02E4", - glottalstopstroke: "02A1", - glottalstopstrokereversed: "02A2", - gmacron: "1E21", - gmonospace: "FF47", - gohiragana: "3054", - gokatakana: "30B4", - gparen: "24A2", - gpasquare: "33AC", - gradient: "2207", - grave: "0060", - gravebelowcmb: "0316", - gravecmb: "0300", - gravecomb: "0300", - gravedeva: "0953", - gravelowmod: "02CE", - gravemonospace: "FF40", - gravetonecmb: "0340", - greater: "003E", - greaterequal: "2265", - greaterequalorless: "22DB", - greatermonospace: "FF1E", - greaterorequivalent: "2273", - greaterorless: "2277", - greateroverequal: "2267", - greatersmall: "FE65", - gscript: "0261", - gstroke: "01E5", - guhiragana: "3050", - guillemotleft: "00AB", - guillemotright: "00BB", - guilsinglleft: "2039", - guilsinglright: "203A", - gukatakana: "30B0", - guramusquare: "3318", - gysquare: "33C9", - h: "0068", - haabkhasiancyrillic: "04A9", - haaltonearabic: "06C1", - habengali: "09B9", - hadescendercyrillic: "04B3", - hadeva: "0939", - hagujarati: "0AB9", - hagurmukhi: "0A39", - haharabic: "062D", - hahfinalarabic: "FEA2", - hahinitialarabic: "FEA3", - hahiragana: "306F", - hahmedialarabic: "FEA4", - haitusquare: "332A", - hakatakana: "30CF", - hakatakanahalfwidth: "FF8A", - halantgurmukhi: "0A4D", - hamzaarabic: "0621", + 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: "0621", + hamzalowarabic: 0x0621, hamzalowkasraarabic: "0621 0650", hamzalowkasratanarabic: "0621 064D", hamzasukunarabic: "0621 0652", - hangulfiller: "3164", - hardsigncyrillic: "044A", - harpoonleftbarbup: "21BC", - harpoonrightbarbup: "21C0", - hasquare: "33CA", - hatafpatah: "05B2", - hatafpatah16: "05B2", - hatafpatah23: "05B2", - hatafpatah2f: "05B2", - hatafpatahhebrew: "05B2", - hatafpatahnarrowhebrew: "05B2", - hatafpatahquarterhebrew: "05B2", - hatafpatahwidehebrew: "05B2", - hatafqamats: "05B3", - hatafqamats1b: "05B3", - hatafqamats28: "05B3", - hatafqamats34: "05B3", - hatafqamatshebrew: "05B3", - hatafqamatsnarrowhebrew: "05B3", - hatafqamatsquarterhebrew: "05B3", - hatafqamatswidehebrew: "05B3", - hatafsegol: "05B1", - hatafsegol17: "05B1", - hatafsegol24: "05B1", - hatafsegol30: "05B1", - hatafsegolhebrew: "05B1", - hatafsegolnarrowhebrew: "05B1", - hatafsegolquarterhebrew: "05B1", - hatafsegolwidehebrew: "05B1", - hbar: "0127", - hbopomofo: "310F", - hbrevebelow: "1E2B", - hcedilla: "1E29", - hcircle: "24D7", - hcircumflex: "0125", - hdieresis: "1E27", - hdotaccent: "1E23", - hdotbelow: "1E25", - he: "05D4", - heart: "2665", - heartsuitblack: "2665", - heartsuitwhite: "2661", - hedagesh: "FB34", - hedageshhebrew: "FB34", - hehaltonearabic: "06C1", - heharabic: "0647", - hehebrew: "05D4", - hehfinalaltonearabic: "FBA7", - hehfinalalttwoarabic: "FEEA", - hehfinalarabic: "FEEA", - hehhamzaabovefinalarabic: "FBA5", - hehhamzaaboveisolatedarabic: "FBA4", - hehinitialaltonearabic: "FBA8", - hehinitialarabic: "FEEB", - hehiragana: "3078", - hehmedialaltonearabic: "FBA9", - hehmedialarabic: "FEEC", - heiseierasquare: "337B", - hekatakana: "30D8", - hekatakanahalfwidth: "FF8D", - hekutaarusquare: "3336", - henghook: "0267", - herutusquare: "3339", - het: "05D7", - hethebrew: "05D7", - hhook: "0266", - hhooksuperior: "02B1", - hieuhacirclekorean: "327B", - hieuhaparenkorean: "321B", - hieuhcirclekorean: "326D", - hieuhkorean: "314E", - hieuhparenkorean: "320D", - hihiragana: "3072", - hikatakana: "30D2", - hikatakanahalfwidth: "FF8B", - hiriq: "05B4", - hiriq14: "05B4", - hiriq21: "05B4", - hiriq2d: "05B4", - hiriqhebrew: "05B4", - hiriqnarrowhebrew: "05B4", - hiriqquarterhebrew: "05B4", - hiriqwidehebrew: "05B4", - hlinebelow: "1E96", - hmonospace: "FF48", - hoarmenian: "0570", - hohipthai: "0E2B", - hohiragana: "307B", - hokatakana: "30DB", - hokatakanahalfwidth: "FF8E", - holam: "05B9", - holam19: "05B9", - holam26: "05B9", - holam32: "05B9", - holamhebrew: "05B9", - holamnarrowhebrew: "05B9", - holamquarterhebrew: "05B9", - holamwidehebrew: "05B9", - honokhukthai: "0E2E", - hookabovecomb: "0309", - hookcmb: "0309", - hookpalatalizedbelowcmb: "0321", - hookretroflexbelowcmb: "0322", - hoonsquare: "3342", - horicoptic: "03E9", - horizontalbar: "2015", - horncmb: "031B", - hotsprings: "2668", - house: "2302", - hparen: "24A3", - hsuperior: "02B0", - hturned: "0265", - huhiragana: "3075", - huiitosquare: "3333", - hukatakana: "30D5", - hukatakanahalfwidth: "FF8C", - hungarumlaut: "02DD", - hungarumlautcmb: "030B", - hv: "0195", - hyphen: "002D", - hypheninferior: "F6E5", - hyphenmonospace: "FF0D", - hyphensmall: "FE63", - hyphensuperior: "F6E6", - hyphentwo: "2010", - i: "0069", - iacute: "00ED", - iacyrillic: "044F", - ibengali: "0987", - ibopomofo: "3127", - ibreve: "012D", - icaron: "01D0", - icircle: "24D8", - icircumflex: "00EE", - icyrillic: "0456", - idblgrave: "0209", - ideographearthcircle: "328F", - ideographfirecircle: "328B", - ideographicallianceparen: "323F", - ideographiccallparen: "323A", - ideographiccentrecircle: "32A5", - ideographicclose: "3006", - ideographiccomma: "3001", - ideographiccommaleft: "FF64", - ideographiccongratulationparen: "3237", - ideographiccorrectcircle: "32A3", - ideographicearthparen: "322F", - ideographicenterpriseparen: "323D", - ideographicexcellentcircle: "329D", - ideographicfestivalparen: "3240", - ideographicfinancialcircle: "3296", - ideographicfinancialparen: "3236", - ideographicfireparen: "322B", - ideographichaveparen: "3232", - ideographichighcircle: "32A4", - ideographiciterationmark: "3005", - ideographiclaborcircle: "3298", - ideographiclaborparen: "3238", - ideographicleftcircle: "32A7", - ideographiclowcircle: "32A6", - ideographicmedicinecircle: "32A9", - ideographicmetalparen: "322E", - ideographicmoonparen: "322A", - ideographicnameparen: "3234", - ideographicperiod: "3002", - ideographicprintcircle: "329E", - ideographicreachparen: "3243", - ideographicrepresentparen: "3239", - ideographicresourceparen: "323E", - ideographicrightcircle: "32A8", - ideographicsecretcircle: "3299", - ideographicselfparen: "3242", - ideographicsocietyparen: "3233", - ideographicspace: "3000", - ideographicspecialparen: "3235", - ideographicstockparen: "3231", - ideographicstudyparen: "323B", - ideographicsunparen: "3230", - ideographicsuperviseparen: "323C", - ideographicwaterparen: "322C", - ideographicwoodparen: "322D", - ideographiczero: "3007", - ideographmetalcircle: "328E", - ideographmooncircle: "328A", - ideographnamecircle: "3294", - ideographsuncircle: "3290", - ideographwatercircle: "328C", - ideographwoodcircle: "328D", - ideva: "0907", - idieresis: "00EF", - idieresisacute: "1E2F", - idieresiscyrillic: "04E5", - idotbelow: "1ECB", - iebrevecyrillic: "04D7", - iecyrillic: "0435", - ieungacirclekorean: "3275", - ieungaparenkorean: "3215", - ieungcirclekorean: "3267", - ieungkorean: "3147", - ieungparenkorean: "3207", - igrave: "00EC", - igujarati: "0A87", - igurmukhi: "0A07", - ihiragana: "3044", - ihookabove: "1EC9", - iibengali: "0988", - iicyrillic: "0438", - iideva: "0908", - iigujarati: "0A88", - iigurmukhi: "0A08", - iimatragurmukhi: "0A40", - iinvertedbreve: "020B", - iishortcyrillic: "0439", - iivowelsignbengali: "09C0", - iivowelsigndeva: "0940", - iivowelsigngujarati: "0AC0", - ij: "0133", - ikatakana: "30A4", - ikatakanahalfwidth: "FF72", - ikorean: "3163", - ilde: "02DC", - iluyhebrew: "05AC", - imacron: "012B", - imacroncyrillic: "04E3", - imageorapproximatelyequal: "2253", - imatragurmukhi: "0A3F", - imonospace: "FF49", - increment: "2206", - infinity: "221E", - iniarmenian: "056B", - integral: "222B", - integralbottom: "2321", - integralbt: "2321", - integralex: "F8F5", - integraltop: "2320", - integraltp: "2320", - intersection: "2229", - intisquare: "3305", - invbullet: "25D8", - invcircle: "25D9", - invsmileface: "263B", - iocyrillic: "0451", - iogonek: "012F", - iota: "03B9", - iotadieresis: "03CA", - iotadieresistonos: "0390", - iotalatin: "0269", - iotatonos: "03AF", - iparen: "24A4", - irigurmukhi: "0A72", - ismallhiragana: "3043", - ismallkatakana: "30A3", - ismallkatakanahalfwidth: "FF68", - issharbengali: "09FA", - istroke: "0268", - isuperior: "F6ED", - iterationhiragana: "309D", - iterationkatakana: "30FD", - itilde: "0129", - itildebelow: "1E2D", - iubopomofo: "3129", - iucyrillic: "044E", - ivowelsignbengali: "09BF", - ivowelsigndeva: "093F", - ivowelsigngujarati: "0ABF", - izhitsacyrillic: "0475", - izhitsadblgravecyrillic: "0477", - j: "006A", - jaarmenian: "0571", - jabengali: "099C", - jadeva: "091C", - jagujarati: "0A9C", - jagurmukhi: "0A1C", - jbopomofo: "3110", - jcaron: "01F0", - jcircle: "24D9", - jcircumflex: "0135", - jcrossedtail: "029D", - jdotlessstroke: "025F", - jecyrillic: "0458", - jeemarabic: "062C", - jeemfinalarabic: "FE9E", - jeeminitialarabic: "FE9F", - jeemmedialarabic: "FEA0", - jeharabic: "0698", - jehfinalarabic: "FB8B", - jhabengali: "099D", - jhadeva: "091D", - jhagujarati: "0A9D", - jhagurmukhi: "0A1D", - jheharmenian: "057B", - jis: "3004", - jmonospace: "FF4A", - jparen: "24A5", - jsuperior: "02B2", - k: "006B", - kabashkircyrillic: "04A1", - kabengali: "0995", - kacute: "1E31", - kacyrillic: "043A", - kadescendercyrillic: "049B", - kadeva: "0915", - kaf: "05DB", - kafarabic: "0643", - kafdagesh: "FB3B", - kafdageshhebrew: "FB3B", - kaffinalarabic: "FEDA", - kafhebrew: "05DB", - kafinitialarabic: "FEDB", - kafmedialarabic: "FEDC", - kafrafehebrew: "FB4D", - kagujarati: "0A95", - kagurmukhi: "0A15", - kahiragana: "304B", - kahookcyrillic: "04C4", - kakatakana: "30AB", - kakatakanahalfwidth: "FF76", - kappa: "03BA", - kappasymbolgreek: "03F0", - kapyeounmieumkorean: "3171", - kapyeounphieuphkorean: "3184", - kapyeounpieupkorean: "3178", - kapyeounssangpieupkorean: "3179", - karoriisquare: "330D", - kashidaautoarabic: "0640", - kashidaautonosidebearingarabic: "0640", - kasmallkatakana: "30F5", - kasquare: "3384", - kasraarabic: "0650", - kasratanarabic: "064D", - kastrokecyrillic: "049F", - katahiraprolongmarkhalfwidth: "FF70", - kaverticalstrokecyrillic: "049D", - kbopomofo: "310E", - kcalsquare: "3389", - kcaron: "01E9", - kcedilla: "0137", - kcircle: "24DA", - kcommaaccent: "0137", - kdotbelow: "1E33", - keharmenian: "0584", - kehiragana: "3051", - kekatakana: "30B1", - kekatakanahalfwidth: "FF79", - kenarmenian: "056F", - kesmallkatakana: "30F6", - kgreenlandic: "0138", - khabengali: "0996", - khacyrillic: "0445", - khadeva: "0916", - khagujarati: "0A96", - khagurmukhi: "0A16", - khaharabic: "062E", - khahfinalarabic: "FEA6", - khahinitialarabic: "FEA7", - khahmedialarabic: "FEA8", - kheicoptic: "03E7", - khhadeva: "0959", - khhagurmukhi: "0A59", - khieukhacirclekorean: "3278", - khieukhaparenkorean: "3218", - khieukhcirclekorean: "326A", - khieukhkorean: "314B", - khieukhparenkorean: "320A", - khokhaithai: "0E02", - khokhonthai: "0E05", - khokhuatthai: "0E03", - khokhwaithai: "0E04", - khomutthai: "0E5B", - khook: "0199", - khorakhangthai: "0E06", - khzsquare: "3391", - kihiragana: "304D", - kikatakana: "30AD", - kikatakanahalfwidth: "FF77", - kiroguramusquare: "3315", - kiromeetorusquare: "3316", - kirosquare: "3314", - kiyeokacirclekorean: "326E", - kiyeokaparenkorean: "320E", - kiyeokcirclekorean: "3260", - kiyeokkorean: "3131", - kiyeokparenkorean: "3200", - kiyeoksioskorean: "3133", - kjecyrillic: "045C", - klinebelow: "1E35", - klsquare: "3398", - kmcubedsquare: "33A6", - kmonospace: "FF4B", - kmsquaredsquare: "33A2", - kohiragana: "3053", - kohmsquare: "33C0", - kokaithai: "0E01", - kokatakana: "30B3", - kokatakanahalfwidth: "FF7A", - kooposquare: "331E", - koppacyrillic: "0481", - koreanstandardsymbol: "327F", - koroniscmb: "0343", - kparen: "24A6", - kpasquare: "33AA", - ksicyrillic: "046F", - ktsquare: "33CF", - kturned: "029E", - kuhiragana: "304F", - kukatakana: "30AF", - kukatakanahalfwidth: "FF78", - kvsquare: "33B8", - kwsquare: "33BE", - l: "006C", - labengali: "09B2", - lacute: "013A", - ladeva: "0932", - lagujarati: "0AB2", - lagurmukhi: "0A32", - lakkhangyaothai: "0E45", - lamaleffinalarabic: "FEFC", - lamalefhamzaabovefinalarabic: "FEF8", - lamalefhamzaaboveisolatedarabic: "FEF7", - lamalefhamzabelowfinalarabic: "FEFA", - lamalefhamzabelowisolatedarabic: "FEF9", - lamalefisolatedarabic: "FEFB", - lamalefmaddaabovefinalarabic: "FEF6", - lamalefmaddaaboveisolatedarabic: "FEF5", - lamarabic: "0644", - lambda: "03BB", - lambdastroke: "019B", - lamed: "05DC", - lameddagesh: "FB3C", - lameddageshhebrew: "FB3C", - lamedhebrew: "05DC", + 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: "FEDE", - lamhahinitialarabic: "FCCA", - laminitialarabic: "FEDF", - lamjeeminitialarabic: "FCC9", - lamkhahinitialarabic: "FCCB", - lamlamhehisolatedarabic: "FDF2", - lammedialarabic: "FEE0", - lammeemhahinitialarabic: "FD88", - lammeeminitialarabic: "FCCC", + 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: "25EF", - lbar: "019A", - lbelt: "026C", - lbopomofo: "310C", - lcaron: "013E", - lcedilla: "013C", - lcircle: "24DB", - lcircumflexbelow: "1E3D", - lcommaaccent: "013C", - ldot: "0140", - ldotaccent: "0140", - ldotbelow: "1E37", - ldotbelowmacron: "1E39", - leftangleabovecmb: "031A", - lefttackbelowcmb: "0318", - less: "003C", - lessequal: "2264", - lessequalorgreater: "22DA", - lessmonospace: "FF1C", - lessorequivalent: "2272", - lessorgreater: "2276", - lessoverequal: "2266", - lesssmall: "FE64", - lezh: "026E", - lfblock: "258C", - lhookretroflex: "026D", - lira: "20A4", - liwnarmenian: "056C", - lj: "01C9", - ljecyrillic: "0459", - ll: "F6C0", - lladeva: "0933", - llagujarati: "0AB3", - llinebelow: "1E3B", - llladeva: "0934", - llvocalicbengali: "09E1", - llvocalicdeva: "0961", - llvocalicvowelsignbengali: "09E3", - llvocalicvowelsigndeva: "0963", - lmiddletilde: "026B", - lmonospace: "FF4C", - lmsquare: "33D0", - lochulathai: "0E2C", - logicaland: "2227", - logicalnot: "00AC", - logicalnotreversed: "2310", - logicalor: "2228", - lolingthai: "0E25", - longs: "017F", - lowlinecenterline: "FE4E", - lowlinecmb: "0332", - lowlinedashed: "FE4D", - lozenge: "25CA", - lparen: "24A7", - lslash: "0142", - lsquare: "2113", - lsuperior: "F6EE", - ltshade: "2591", - luthai: "0E26", - lvocalicbengali: "098C", - lvocalicdeva: "090C", - lvocalicvowelsignbengali: "09E2", - lvocalicvowelsigndeva: "0962", - lxsquare: "33D3", - m: "006D", - mabengali: "09AE", - macron: "00AF", - macronbelowcmb: "0331", - macroncmb: "0304", - macronlowmod: "02CD", - macronmonospace: "FFE3", - macute: "1E3F", - madeva: "092E", - magujarati: "0AAE", - magurmukhi: "0A2E", - mahapakhhebrew: "05A4", - mahapakhlefthebrew: "05A4", - mahiragana: "307E", - maichattawalowleftthai: "F895", - maichattawalowrightthai: "F894", - maichattawathai: "0E4B", - maichattawaupperleftthai: "F893", - maieklowleftthai: "F88C", - maieklowrightthai: "F88B", - maiekthai: "0E48", - maiekupperleftthai: "F88A", - maihanakatleftthai: "F884", - maihanakatthai: "0E31", - maitaikhuleftthai: "F889", - maitaikhuthai: "0E47", - maitholowleftthai: "F88F", - maitholowrightthai: "F88E", - maithothai: "0E49", - maithoupperleftthai: "F88D", - maitrilowleftthai: "F892", - maitrilowrightthai: "F891", - maitrithai: "0E4A", - maitriupperleftthai: "F890", - maiyamokthai: "0E46", - makatakana: "30DE", - makatakanahalfwidth: "FF8F", - male: "2642", - mansyonsquare: "3347", - maqafhebrew: "05BE", - mars: "2642", - masoracirclehebrew: "05AF", - masquare: "3383", - mbopomofo: "3107", - mbsquare: "33D4", - mcircle: "24DC", - mcubedsquare: "33A5", - mdotaccent: "1E41", - mdotbelow: "1E43", - meemarabic: "0645", - meemfinalarabic: "FEE2", - meeminitialarabic: "FEE3", - meemmedialarabic: "FEE4", - meemmeeminitialarabic: "FCD1", - meemmeemisolatedarabic: "FC48", - meetorusquare: "334D", - mehiragana: "3081", - meizierasquare: "337E", - mekatakana: "30E1", - mekatakanahalfwidth: "FF92", - mem: "05DE", - memdagesh: "FB3E", - memdageshhebrew: "FB3E", - memhebrew: "05DE", - menarmenian: "0574", - merkhahebrew: "05A5", - merkhakefulahebrew: "05A6", - merkhakefulalefthebrew: "05A6", - merkhalefthebrew: "05A5", - mhook: "0271", - mhzsquare: "3392", - middledotkatakanahalfwidth: "FF65", - middot: "00B7", - mieumacirclekorean: "3272", - mieumaparenkorean: "3212", - mieumcirclekorean: "3264", - mieumkorean: "3141", - mieumpansioskorean: "3170", - mieumparenkorean: "3204", - mieumpieupkorean: "316E", - mieumsioskorean: "316F", - mihiragana: "307F", - mikatakana: "30DF", - mikatakanahalfwidth: "FF90", - minus: "2212", - minusbelowcmb: "0320", - minuscircle: "2296", - minusmod: "02D7", - minusplus: "2213", - minute: "2032", - miribaarusquare: "334A", - mirisquare: "3349", - mlonglegturned: "0270", - mlsquare: "3396", - mmcubedsquare: "33A3", - mmonospace: "FF4D", - mmsquaredsquare: "339F", - mohiragana: "3082", - mohmsquare: "33C1", - mokatakana: "30E2", - mokatakanahalfwidth: "FF93", - molsquare: "33D6", - momathai: "0E21", - moverssquare: "33A7", - moverssquaredsquare: "33A8", - mparen: "24A8", - mpasquare: "33AB", - mssquare: "33B3", - msuperior: "F6EF", - mturned: "026F", - mu: "00B5", - mu1: "00B5", - muasquare: "3382", - muchgreater: "226B", - muchless: "226A", - mufsquare: "338C", - mugreek: "03BC", - mugsquare: "338D", - muhiragana: "3080", - mukatakana: "30E0", - mukatakanahalfwidth: "FF91", - mulsquare: "3395", - multiply: "00D7", - mumsquare: "339B", - munahhebrew: "05A3", - munahlefthebrew: "05A3", - musicalnote: "266A", - musicalnotedbl: "266B", - musicflatsign: "266D", - musicsharpsign: "266F", - mussquare: "33B2", - muvsquare: "33B6", - muwsquare: "33BC", - mvmegasquare: "33B9", - mvsquare: "33B7", - mwmegasquare: "33BF", - mwsquare: "33BD", - n: "006E", - nabengali: "09A8", - nabla: "2207", - nacute: "0144", - nadeva: "0928", - nagujarati: "0AA8", - nagurmukhi: "0A28", - nahiragana: "306A", - nakatakana: "30CA", - nakatakanahalfwidth: "FF85", - napostrophe: "0149", - nasquare: "3381", - nbopomofo: "310B", - nbspace: "00A0", - ncaron: "0148", - ncedilla: "0146", - ncircle: "24DD", - ncircumflexbelow: "1E4B", - ncommaaccent: "0146", - ndotaccent: "1E45", - ndotbelow: "1E47", - nehiragana: "306D", - nekatakana: "30CD", - nekatakanahalfwidth: "FF88", - newsheqelsign: "20AA", - nfsquare: "338B", - ngabengali: "0999", - ngadeva: "0919", - ngagujarati: "0A99", - ngagurmukhi: "0A19", - ngonguthai: "0E07", - nhiragana: "3093", - nhookleft: "0272", - nhookretroflex: "0273", - nieunacirclekorean: "326F", - nieunaparenkorean: "320F", - nieuncieuckorean: "3135", - nieuncirclekorean: "3261", - nieunhieuhkorean: "3136", - nieunkorean: "3134", - nieunpansioskorean: "3168", - nieunparenkorean: "3201", - nieunsioskorean: "3167", - nieuntikeutkorean: "3166", - nihiragana: "306B", - nikatakana: "30CB", - nikatakanahalfwidth: "FF86", - nikhahitleftthai: "F899", - nikhahitthai: "0E4D", - nine: "0039", - ninearabic: "0669", - ninebengali: "09EF", - ninecircle: "2468", - ninecircleinversesansserif: "2792", - ninedeva: "096F", - ninegujarati: "0AEF", - ninegurmukhi: "0A6F", - ninehackarabic: "0669", - ninehangzhou: "3029", - nineideographicparen: "3228", - nineinferior: "2089", - ninemonospace: "FF19", - nineoldstyle: "F739", - nineparen: "247C", - nineperiod: "2490", - ninepersian: "06F9", - nineroman: "2178", - ninesuperior: "2079", - nineteencircle: "2472", - nineteenparen: "2486", - nineteenperiod: "249A", - ninethai: "0E59", - nj: "01CC", - njecyrillic: "045A", - nkatakana: "30F3", - nkatakanahalfwidth: "FF9D", - nlegrightlong: "019E", - nlinebelow: "1E49", - nmonospace: "FF4E", - nmsquare: "339A", - nnabengali: "09A3", - nnadeva: "0923", - nnagujarati: "0AA3", - nnagurmukhi: "0A23", - nnnadeva: "0929", - nohiragana: "306E", - nokatakana: "30CE", - nokatakanahalfwidth: "FF89", - nonbreakingspace: "00A0", - nonenthai: "0E13", - nonuthai: "0E19", - noonarabic: "0646", - noonfinalarabic: "FEE6", - noonghunnaarabic: "06BA", - noonghunnafinalarabic: "FB9F", + 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: "FEE7", - noonjeeminitialarabic: "FCD2", - noonjeemisolatedarabic: "FC4B", - noonmedialarabic: "FEE8", - noonmeeminitialarabic: "FCD5", - noonmeemisolatedarabic: "FC4E", - noonnoonfinalarabic: "FC8D", - notcontains: "220C", - notelement: "2209", - notelementof: "2209", - notequal: "2260", - notgreater: "226F", - notgreaternorequal: "2271", - notgreaternorless: "2279", - notidentical: "2262", - notless: "226E", - notlessnorequal: "2270", - notparallel: "2226", - notprecedes: "2280", - notsubset: "2284", - notsucceeds: "2281", - notsuperset: "2285", - nowarmenian: "0576", - nparen: "24A9", - nssquare: "33B1", - nsuperior: "207F", - ntilde: "00F1", - nu: "03BD", - nuhiragana: "306C", - nukatakana: "30CC", - nukatakanahalfwidth: "FF87", - nuktabengali: "09BC", - nuktadeva: "093C", - nuktagujarati: "0ABC", - nuktagurmukhi: "0A3C", - numbersign: "0023", - numbersignmonospace: "FF03", - numbersignsmall: "FE5F", - numeralsigngreek: "0374", - numeralsignlowergreek: "0375", - numero: "2116", - nun: "05E0", - nundagesh: "FB40", - nundageshhebrew: "FB40", - nunhebrew: "05E0", - nvsquare: "33B5", - nwsquare: "33BB", - nyabengali: "099E", - nyadeva: "091E", - nyagujarati: "0A9E", - nyagurmukhi: "0A1E", - o: "006F", - oacute: "00F3", - oangthai: "0E2D", - obarred: "0275", - obarredcyrillic: "04E9", - obarreddieresiscyrillic: "04EB", - obengali: "0993", - obopomofo: "311B", - obreve: "014F", - ocandradeva: "0911", - ocandragujarati: "0A91", - ocandravowelsigndeva: "0949", - ocandravowelsigngujarati: "0AC9", - ocaron: "01D2", - ocircle: "24DE", - ocircumflex: "00F4", - ocircumflexacute: "1ED1", - ocircumflexdotbelow: "1ED9", - ocircumflexgrave: "1ED3", - ocircumflexhookabove: "1ED5", - ocircumflextilde: "1ED7", - ocyrillic: "043E", - odblacute: "0151", - odblgrave: "020D", - odeva: "0913", - odieresis: "00F6", - odieresiscyrillic: "04E7", - odotbelow: "1ECD", - oe: "0153", - oekorean: "315A", - ogonek: "02DB", - ogonekcmb: "0328", - ograve: "00F2", - ogujarati: "0A93", - oharmenian: "0585", - ohiragana: "304A", - ohookabove: "1ECF", - ohorn: "01A1", - ohornacute: "1EDB", - ohorndotbelow: "1EE3", - ohorngrave: "1EDD", - ohornhookabove: "1EDF", - ohorntilde: "1EE1", - ohungarumlaut: "0151", - oi: "01A3", - oinvertedbreve: "020F", - okatakana: "30AA", - okatakanahalfwidth: "FF75", - okorean: "3157", - olehebrew: "05AB", - omacron: "014D", - omacronacute: "1E53", - omacrongrave: "1E51", - omdeva: "0950", - omega: "03C9", - omega1: "03D6", - omegacyrillic: "0461", - omegalatinclosed: "0277", - omegaroundcyrillic: "047B", - omegatitlocyrillic: "047D", - omegatonos: "03CE", - omgujarati: "0AD0", - omicron: "03BF", - omicrontonos: "03CC", - omonospace: "FF4F", - one: "0031", - onearabic: "0661", - onebengali: "09E7", - onecircle: "2460", - onecircleinversesansserif: "278A", - onedeva: "0967", - onedotenleader: "2024", - oneeighth: "215B", - onefitted: "F6DC", - onegujarati: "0AE7", - onegurmukhi: "0A67", - onehackarabic: "0661", - onehalf: "00BD", - onehangzhou: "3021", - oneideographicparen: "3220", - oneinferior: "2081", - onemonospace: "FF11", - onenumeratorbengali: "09F4", - oneoldstyle: "F731", - oneparen: "2474", - oneperiod: "2488", - onepersian: "06F1", - onequarter: "00BC", - oneroman: "2170", - onesuperior: "00B9", - onethai: "0E51", - onethird: "2153", - oogonek: "01EB", - oogonekmacron: "01ED", - oogurmukhi: "0A13", - oomatragurmukhi: "0A4B", - oopen: "0254", - oparen: "24AA", - openbullet: "25E6", - option: "2325", - ordfeminine: "00AA", - ordmasculine: "00BA", - orthogonal: "221F", - oshortdeva: "0912", - oshortvowelsigndeva: "094A", - oslash: "00F8", - oslashacute: "01FF", - osmallhiragana: "3049", - osmallkatakana: "30A9", - osmallkatakanahalfwidth: "FF6B", - ostrokeacute: "01FF", - osuperior: "F6F0", - otcyrillic: "047F", - otilde: "00F5", - otildeacute: "1E4D", - otildedieresis: "1E4F", - oubopomofo: "3121", - overline: "203E", - overlinecenterline: "FE4A", - overlinecmb: "0305", - overlinedashed: "FE49", - overlinedblwavy: "FE4C", - overlinewavy: "FE4B", - overscore: "00AF", - ovowelsignbengali: "09CB", - ovowelsigndeva: "094B", - ovowelsigngujarati: "0ACB", - p: "0070", - paampssquare: "3380", - paasentosquare: "332B", - pabengali: "09AA", - pacute: "1E55", - padeva: "092A", - pagedown: "21DF", - pageup: "21DE", - pagujarati: "0AAA", - pagurmukhi: "0A2A", - pahiragana: "3071", - paiyannoithai: "0E2F", - pakatakana: "30D1", - palatalizationcyrilliccmb: "0484", - palochkacyrillic: "04C0", - pansioskorean: "317F", - paragraph: "00B6", - parallel: "2225", - parenleft: "0028", - parenleftaltonearabic: "FD3E", - parenleftbt: "F8ED", - parenleftex: "F8EC", - parenleftinferior: "208D", - parenleftmonospace: "FF08", - parenleftsmall: "FE59", - parenleftsuperior: "207D", - parenlefttp: "F8EB", - parenleftvertical: "FE35", - parenright: "0029", - parenrightaltonearabic: "FD3F", - parenrightbt: "F8F8", - parenrightex: "F8F7", - parenrightinferior: "208E", - parenrightmonospace: "FF09", - parenrightsmall: "FE5A", - parenrightsuperior: "207E", - parenrighttp: "F8F6", - parenrightvertical: "FE36", - partialdiff: "2202", - paseqhebrew: "05C0", - pashtahebrew: "0599", - pasquare: "33A9", - patah: "05B7", - patah11: "05B7", - patah1d: "05B7", - patah2a: "05B7", - patahhebrew: "05B7", - patahnarrowhebrew: "05B7", - patahquarterhebrew: "05B7", - patahwidehebrew: "05B7", - pazerhebrew: "05A1", - pbopomofo: "3106", - pcircle: "24DF", - pdotaccent: "1E57", - pe: "05E4", - pecyrillic: "043F", - pedagesh: "FB44", - pedageshhebrew: "FB44", - peezisquare: "333B", - pefinaldageshhebrew: "FB43", - peharabic: "067E", - peharmenian: "057A", - pehebrew: "05E4", - pehfinalarabic: "FB57", - pehinitialarabic: "FB58", - pehiragana: "307A", - pehmedialarabic: "FB59", - pekatakana: "30DA", - pemiddlehookcyrillic: "04A7", - perafehebrew: "FB4E", - percent: "0025", - percentarabic: "066A", - percentmonospace: "FF05", - percentsmall: "FE6A", - period: "002E", - periodarmenian: "0589", - periodcentered: "00B7", - periodhalfwidth: "FF61", - periodinferior: "F6E7", - periodmonospace: "FF0E", - periodsmall: "FE52", - periodsuperior: "F6E8", - perispomenigreekcmb: "0342", - perpendicular: "22A5", - perthousand: "2030", - peseta: "20A7", - pfsquare: "338A", - phabengali: "09AB", - phadeva: "092B", - phagujarati: "0AAB", - phagurmukhi: "0A2B", - phi: "03C6", - phi1: "03D5", - phieuphacirclekorean: "327A", - phieuphaparenkorean: "321A", - phieuphcirclekorean: "326C", - phieuphkorean: "314D", - phieuphparenkorean: "320C", - philatin: "0278", - phinthuthai: "0E3A", - phisymbolgreek: "03D5", - phook: "01A5", - phophanthai: "0E1E", - phophungthai: "0E1C", - phosamphaothai: "0E20", - pi: "03C0", - pieupacirclekorean: "3273", - pieupaparenkorean: "3213", - pieupcieuckorean: "3176", - pieupcirclekorean: "3265", - pieupkiyeokkorean: "3172", - pieupkorean: "3142", - pieupparenkorean: "3205", - pieupsioskiyeokkorean: "3174", - pieupsioskorean: "3144", - pieupsiostikeutkorean: "3175", - pieupthieuthkorean: "3177", - pieuptikeutkorean: "3173", - pihiragana: "3074", - pikatakana: "30D4", - pisymbolgreek: "03D6", - piwrarmenian: "0583", - plus: "002B", - plusbelowcmb: "031F", - pluscircle: "2295", - plusminus: "00B1", - plusmod: "02D6", - plusmonospace: "FF0B", - plussmall: "FE62", - plussuperior: "207A", - pmonospace: "FF50", - pmsquare: "33D8", - pohiragana: "307D", - pointingindexdownwhite: "261F", - pointingindexleftwhite: "261C", - pointingindexrightwhite: "261E", - pointingindexupwhite: "261D", - pokatakana: "30DD", - poplathai: "0E1B", - postalmark: "3012", - postalmarkface: "3020", - pparen: "24AB", - precedes: "227A", - prescription: "211E", - primemod: "02B9", - primereversed: "2035", - product: "220F", - projective: "2305", - prolongedkana: "30FC", - propellor: "2318", - propersubset: "2282", - propersuperset: "2283", - proportion: "2237", - proportional: "221D", - psi: "03C8", - psicyrillic: "0471", - psilipneumatacyrilliccmb: "0486", - pssquare: "33B0", - puhiragana: "3077", - pukatakana: "30D7", - pvsquare: "33B4", - pwsquare: "33BA", - q: "0071", - qadeva: "0958", - qadmahebrew: "05A8", - qafarabic: "0642", - qaffinalarabic: "FED6", - qafinitialarabic: "FED7", - qafmedialarabic: "FED8", - qamats: "05B8", - qamats10: "05B8", - qamats1a: "05B8", - qamats1c: "05B8", - qamats27: "05B8", - qamats29: "05B8", - qamats33: "05B8", - qamatsde: "05B8", - qamatshebrew: "05B8", - qamatsnarrowhebrew: "05B8", - qamatsqatanhebrew: "05B8", - qamatsqatannarrowhebrew: "05B8", - qamatsqatanquarterhebrew: "05B8", - qamatsqatanwidehebrew: "05B8", - qamatsquarterhebrew: "05B8", - qamatswidehebrew: "05B8", - qarneyparahebrew: "059F", - qbopomofo: "3111", - qcircle: "24E0", - qhook: "02A0", - qmonospace: "FF51", - qof: "05E7", - qofdagesh: "FB47", - qofdageshhebrew: "FB47", + 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: "05E7", + qofhebrew: 0x05E7, qofhiriq: "05E7 05B4", qofhiriqhebrew: "05E7 05B4", qofholam: "05E7 05B9", @@ -3172,89 +3172,89 @@ var GlyphsUnicode = { qofshevahebrew: "05E7 05B0", qoftsere: "05E7 05B5", qoftserehebrew: "05E7 05B5", - qparen: "24AC", - quarternote: "2669", - qubuts: "05BB", - qubuts18: "05BB", - qubuts25: "05BB", - qubuts31: "05BB", - qubutshebrew: "05BB", - qubutsnarrowhebrew: "05BB", - qubutsquarterhebrew: "05BB", - qubutswidehebrew: "05BB", - question: "003F", - questionarabic: "061F", - questionarmenian: "055E", - questiondown: "00BF", - questiondownsmall: "F7BF", - questiongreek: "037E", - questionmonospace: "FF1F", - questionsmall: "F73F", - quotedbl: "0022", - quotedblbase: "201E", - quotedblleft: "201C", - quotedblmonospace: "FF02", - quotedblprime: "301E", - quotedblprimereversed: "301D", - quotedblright: "201D", - quoteleft: "2018", - quoteleftreversed: "201B", - quotereversed: "201B", - quoteright: "2019", - quoterightn: "0149", - quotesinglbase: "201A", - quotesingle: "0027", - quotesinglemonospace: "FF07", - r: "0072", - raarmenian: "057C", - rabengali: "09B0", - racute: "0155", - radeva: "0930", - radical: "221A", - radicalex: "F8E5", - radoverssquare: "33AE", - radoverssquaredsquare: "33AF", - radsquare: "33AD", - rafe: "05BF", - rafehebrew: "05BF", - ragujarati: "0AB0", - ragurmukhi: "0A30", - rahiragana: "3089", - rakatakana: "30E9", - rakatakanahalfwidth: "FF97", - ralowerdiagonalbengali: "09F1", - ramiddlediagonalbengali: "09F0", - ramshorn: "0264", - ratio: "2236", - rbopomofo: "3116", - rcaron: "0159", - rcedilla: "0157", - rcircle: "24E1", - rcommaaccent: "0157", - rdblgrave: "0211", - rdotaccent: "1E59", - rdotbelow: "1E5B", - rdotbelowmacron: "1E5D", - referencemark: "203B", - reflexsubset: "2286", - reflexsuperset: "2287", - registered: "00AE", - registersans: "F8E8", - registerserif: "F6DA", - reharabic: "0631", - reharmenian: "0580", - rehfinalarabic: "FEAE", - rehiragana: "308C", + 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: "30EC", - rekatakanahalfwidth: "FF9A", - resh: "05E8", - reshdageshhebrew: "FB48", + rekatakana: 0x30EC, + rekatakanahalfwidth: 0xFF9A, + resh: 0x05E8, + reshdageshhebrew: 0xFB48, reshhatafpatah: "05E8 05B2", reshhatafpatahhebrew: "05E8 05B2", reshhatafsegol: "05E8 05B1", reshhatafsegolhebrew: "05E8 05B1", - reshhebrew: "05E8", + reshhebrew: 0x05E8, reshhiriq: "05E8 05B4", reshhiriqhebrew: "05E8 05B4", reshholam: "05E8 05B9", @@ -3271,1019 +3271,1019 @@ var GlyphsUnicode = { reshshevahebrew: "05E8 05B0", reshtsere: "05E8 05B5", reshtserehebrew: "05E8 05B5", - reversedtilde: "223D", - reviahebrew: "0597", - reviamugrashhebrew: "0597", - revlogicalnot: "2310", - rfishhook: "027E", - rfishhookreversed: "027F", - rhabengali: "09DD", - rhadeva: "095D", - rho: "03C1", - rhook: "027D", - rhookturned: "027B", - rhookturnedsuperior: "02B5", - rhosymbolgreek: "03F1", - rhotichookmod: "02DE", - rieulacirclekorean: "3271", - rieulaparenkorean: "3211", - rieulcirclekorean: "3263", - rieulhieuhkorean: "3140", - rieulkiyeokkorean: "313A", - rieulkiyeoksioskorean: "3169", - rieulkorean: "3139", - rieulmieumkorean: "313B", - rieulpansioskorean: "316C", - rieulparenkorean: "3203", - rieulphieuphkorean: "313F", - rieulpieupkorean: "313C", - rieulpieupsioskorean: "316B", - rieulsioskorean: "313D", - rieulthieuthkorean: "313E", - rieultikeutkorean: "316A", - rieulyeorinhieuhkorean: "316D", - rightangle: "221F", - righttackbelowcmb: "0319", - righttriangle: "22BF", - rihiragana: "308A", - rikatakana: "30EA", - rikatakanahalfwidth: "FF98", - ring: "02DA", - ringbelowcmb: "0325", - ringcmb: "030A", - ringhalfleft: "02BF", - ringhalfleftarmenian: "0559", - ringhalfleftbelowcmb: "031C", - ringhalfleftcentered: "02D3", - ringhalfright: "02BE", - ringhalfrightbelowcmb: "0339", - ringhalfrightcentered: "02D2", - rinvertedbreve: "0213", - rittorusquare: "3351", - rlinebelow: "1E5F", - rlongleg: "027C", - rlonglegturned: "027A", - rmonospace: "FF52", - rohiragana: "308D", - rokatakana: "30ED", - rokatakanahalfwidth: "FF9B", - roruathai: "0E23", - rparen: "24AD", - rrabengali: "09DC", - rradeva: "0931", - rragurmukhi: "0A5C", - rreharabic: "0691", - rrehfinalarabic: "FB8D", - rrvocalicbengali: "09E0", - rrvocalicdeva: "0960", - rrvocalicgujarati: "0AE0", - rrvocalicvowelsignbengali: "09C4", - rrvocalicvowelsigndeva: "0944", - rrvocalicvowelsigngujarati: "0AC4", - rsuperior: "F6F1", - rtblock: "2590", - rturned: "0279", - rturnedsuperior: "02B4", - ruhiragana: "308B", - rukatakana: "30EB", - rukatakanahalfwidth: "FF99", - rupeemarkbengali: "09F2", - rupeesignbengali: "09F3", - rupiah: "F6DD", - ruthai: "0E24", - rvocalicbengali: "098B", - rvocalicdeva: "090B", - rvocalicgujarati: "0A8B", - rvocalicvowelsignbengali: "09C3", - rvocalicvowelsigndeva: "0943", - rvocalicvowelsigngujarati: "0AC3", - s: "0073", - sabengali: "09B8", - sacute: "015B", - sacutedotaccent: "1E65", - sadarabic: "0635", - sadeva: "0938", - sadfinalarabic: "FEBA", - sadinitialarabic: "FEBB", - sadmedialarabic: "FEBC", - sagujarati: "0AB8", - sagurmukhi: "0A38", - sahiragana: "3055", - sakatakana: "30B5", - sakatakanahalfwidth: "FF7B", - sallallahoualayhewasallamarabic: "FDFA", - samekh: "05E1", - samekhdagesh: "FB41", - samekhdageshhebrew: "FB41", - samekhhebrew: "05E1", - saraaathai: "0E32", - saraaethai: "0E41", - saraaimaimalaithai: "0E44", - saraaimaimuanthai: "0E43", - saraamthai: "0E33", - saraathai: "0E30", - saraethai: "0E40", - saraiileftthai: "F886", - saraiithai: "0E35", - saraileftthai: "F885", - saraithai: "0E34", - saraothai: "0E42", - saraueeleftthai: "F888", - saraueethai: "0E37", - saraueleftthai: "F887", - sarauethai: "0E36", - sarauthai: "0E38", - sarauuthai: "0E39", - sbopomofo: "3119", - scaron: "0161", - scarondotaccent: "1E67", - scedilla: "015F", - schwa: "0259", - schwacyrillic: "04D9", - schwadieresiscyrillic: "04DB", - schwahook: "025A", - scircle: "24E2", - scircumflex: "015D", - scommaaccent: "0219", - sdotaccent: "1E61", - sdotbelow: "1E63", - sdotbelowdotaccent: "1E69", - seagullbelowcmb: "033C", - second: "2033", - secondtonechinese: "02CA", - section: "00A7", - seenarabic: "0633", - seenfinalarabic: "FEB2", - seeninitialarabic: "FEB3", - seenmedialarabic: "FEB4", - segol: "05B6", - segol13: "05B6", - segol1f: "05B6", - segol2c: "05B6", - segolhebrew: "05B6", - segolnarrowhebrew: "05B6", - segolquarterhebrew: "05B6", - segoltahebrew: "0592", - segolwidehebrew: "05B6", - seharmenian: "057D", - sehiragana: "305B", - sekatakana: "30BB", - sekatakanahalfwidth: "FF7E", - semicolon: "003B", - semicolonarabic: "061B", - semicolonmonospace: "FF1B", - semicolonsmall: "FE54", - semivoicedmarkkana: "309C", - semivoicedmarkkanahalfwidth: "FF9F", - sentisquare: "3322", - sentosquare: "3323", - seven: "0037", - sevenarabic: "0667", - sevenbengali: "09ED", - sevencircle: "2466", - sevencircleinversesansserif: "2790", - sevendeva: "096D", - seveneighths: "215E", - sevengujarati: "0AED", - sevengurmukhi: "0A6D", - sevenhackarabic: "0667", - sevenhangzhou: "3027", - sevenideographicparen: "3226", - seveninferior: "2087", - sevenmonospace: "FF17", - sevenoldstyle: "F737", - sevenparen: "247A", - sevenperiod: "248E", - sevenpersian: "06F7", - sevenroman: "2176", - sevensuperior: "2077", - seventeencircle: "2470", - seventeenparen: "2484", - seventeenperiod: "2498", - seventhai: "0E57", - sfthyphen: "00AD", - shaarmenian: "0577", - shabengali: "09B6", - shacyrillic: "0448", - shaddaarabic: "0651", - shaddadammaarabic: "FC61", - shaddadammatanarabic: "FC5E", - shaddafathaarabic: "FC60", + 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: "FC62", - shaddakasratanarabic: "FC5F", - shade: "2592", - shadedark: "2593", - shadelight: "2591", - shademedium: "2592", - shadeva: "0936", - shagujarati: "0AB6", - shagurmukhi: "0A36", - shalshelethebrew: "0593", - shbopomofo: "3115", - shchacyrillic: "0449", - sheenarabic: "0634", - sheenfinalarabic: "FEB6", - sheeninitialarabic: "FEB7", - sheenmedialarabic: "FEB8", - sheicoptic: "03E3", - sheqel: "20AA", - sheqelhebrew: "20AA", - sheva: "05B0", - sheva115: "05B0", - sheva15: "05B0", - sheva22: "05B0", - sheva2e: "05B0", - shevahebrew: "05B0", - shevanarrowhebrew: "05B0", - shevaquarterhebrew: "05B0", - shevawidehebrew: "05B0", - shhacyrillic: "04BB", - shimacoptic: "03ED", - shin: "05E9", - shindagesh: "FB49", - shindageshhebrew: "FB49", - shindageshshindot: "FB2C", - shindageshshindothebrew: "FB2C", - shindageshsindot: "FB2D", - shindageshsindothebrew: "FB2D", - shindothebrew: "05C1", - shinhebrew: "05E9", - shinshindot: "FB2A", - shinshindothebrew: "FB2A", - shinsindot: "FB2B", - shinsindothebrew: "FB2B", - shook: "0282", - sigma: "03C3", - sigma1: "03C2", - sigmafinal: "03C2", - sigmalunatesymbolgreek: "03F2", - sihiragana: "3057", - sikatakana: "30B7", - sikatakanahalfwidth: "FF7C", - siluqhebrew: "05BD", - siluqlefthebrew: "05BD", - similar: "223C", - sindothebrew: "05C2", - siosacirclekorean: "3274", - siosaparenkorean: "3214", - sioscieuckorean: "317E", - sioscirclekorean: "3266", - sioskiyeokkorean: "317A", - sioskorean: "3145", - siosnieunkorean: "317B", - siosparenkorean: "3206", - siospieupkorean: "317D", - siostikeutkorean: "317C", - six: "0036", - sixarabic: "0666", - sixbengali: "09EC", - sixcircle: "2465", - sixcircleinversesansserif: "278F", - sixdeva: "096C", - sixgujarati: "0AEC", - sixgurmukhi: "0A6C", - sixhackarabic: "0666", - sixhangzhou: "3026", - sixideographicparen: "3225", - sixinferior: "2086", - sixmonospace: "FF16", - sixoldstyle: "F736", - sixparen: "2479", - sixperiod: "248D", - sixpersian: "06F6", - sixroman: "2175", - sixsuperior: "2076", - sixteencircle: "246F", - sixteencurrencydenominatorbengali: "09F9", - sixteenparen: "2483", - sixteenperiod: "2497", - sixthai: "0E56", - slash: "002F", - slashmonospace: "FF0F", - slong: "017F", - slongdotaccent: "1E9B", - smileface: "263A", - smonospace: "FF53", - sofpasuqhebrew: "05C3", - softhyphen: "00AD", - softsigncyrillic: "044C", - sohiragana: "305D", - sokatakana: "30BD", - sokatakanahalfwidth: "FF7F", - soliduslongoverlaycmb: "0338", - solidusshortoverlaycmb: "0337", - sorusithai: "0E29", - sosalathai: "0E28", - sosothai: "0E0B", - sosuathai: "0E2A", - space: "0020", - spacehackarabic: "0020", - spade: "2660", - spadesuitblack: "2660", - spadesuitwhite: "2664", - sparen: "24AE", - squarebelowcmb: "033B", - squarecc: "33C4", - squarecm: "339D", - squarediagonalcrosshatchfill: "25A9", - squarehorizontalfill: "25A4", - squarekg: "338F", - squarekm: "339E", - squarekmcapital: "33CE", - squareln: "33D1", - squarelog: "33D2", - squaremg: "338E", - squaremil: "33D5", - squaremm: "339C", - squaremsquared: "33A1", - squareorthogonalcrosshatchfill: "25A6", - squareupperlefttolowerrightfill: "25A7", - squareupperrighttolowerleftfill: "25A8", - squareverticalfill: "25A5", - squarewhitewithsmallblack: "25A3", - srsquare: "33DB", - ssabengali: "09B7", - ssadeva: "0937", - ssagujarati: "0AB7", - ssangcieuckorean: "3149", - ssanghieuhkorean: "3185", - ssangieungkorean: "3180", - ssangkiyeokkorean: "3132", - ssangnieunkorean: "3165", - ssangpieupkorean: "3143", - ssangsioskorean: "3146", - ssangtikeutkorean: "3138", - ssuperior: "F6F2", - sterling: "00A3", - sterlingmonospace: "FFE1", - strokelongoverlaycmb: "0336", - strokeshortoverlaycmb: "0335", - subset: "2282", - subsetnotequal: "228A", - subsetorequal: "2286", - succeeds: "227B", - suchthat: "220B", - suhiragana: "3059", - sukatakana: "30B9", - sukatakanahalfwidth: "FF7D", - sukunarabic: "0652", - summation: "2211", - sun: "263C", - superset: "2283", - supersetnotequal: "228B", - supersetorequal: "2287", - svsquare: "33DC", - syouwaerasquare: "337C", - t: "0074", - tabengali: "09A4", - tackdown: "22A4", - tackleft: "22A3", - tadeva: "0924", - tagujarati: "0AA4", - tagurmukhi: "0A24", - taharabic: "0637", - tahfinalarabic: "FEC2", - tahinitialarabic: "FEC3", - tahiragana: "305F", - tahmedialarabic: "FEC4", - taisyouerasquare: "337D", - takatakana: "30BF", - takatakanahalfwidth: "FF80", - tatweelarabic: "0640", - tau: "03C4", - tav: "05EA", - tavdages: "FB4A", - tavdagesh: "FB4A", - tavdageshhebrew: "FB4A", - tavhebrew: "05EA", - tbar: "0167", - tbopomofo: "310A", - tcaron: "0165", - tccurl: "02A8", - tcedilla: "0163", - tcheharabic: "0686", - tchehfinalarabic: "FB7B", - tchehinitialarabic: "FB7C", - tchehmedialarabic: "FB7D", + 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: "24E3", - tcircumflexbelow: "1E71", - tcommaaccent: "0163", - tdieresis: "1E97", - tdotaccent: "1E6B", - tdotbelow: "1E6D", - tecyrillic: "0442", - tedescendercyrillic: "04AD", - teharabic: "062A", - tehfinalarabic: "FE96", - tehhahinitialarabic: "FCA2", - tehhahisolatedarabic: "FC0C", - tehinitialarabic: "FE97", - tehiragana: "3066", - tehjeeminitialarabic: "FCA1", - tehjeemisolatedarabic: "FC0B", - tehmarbutaarabic: "0629", - tehmarbutafinalarabic: "FE94", - tehmedialarabic: "FE98", - tehmeeminitialarabic: "FCA4", - tehmeemisolatedarabic: "FC0E", - tehnoonfinalarabic: "FC73", - tekatakana: "30C6", - tekatakanahalfwidth: "FF83", - telephone: "2121", - telephoneblack: "260E", - telishagedolahebrew: "05A0", - telishaqetanahebrew: "05A9", - tencircle: "2469", - tenideographicparen: "3229", - tenparen: "247D", - tenperiod: "2491", - tenroman: "2179", - tesh: "02A7", - tet: "05D8", - tetdagesh: "FB38", - tetdageshhebrew: "FB38", - tethebrew: "05D8", - tetsecyrillic: "04B5", - tevirhebrew: "059B", - tevirlefthebrew: "059B", - thabengali: "09A5", - thadeva: "0925", - thagujarati: "0AA5", - thagurmukhi: "0A25", - thalarabic: "0630", - thalfinalarabic: "FEAC", - thanthakhatlowleftthai: "F898", - thanthakhatlowrightthai: "F897", - thanthakhatthai: "0E4C", - thanthakhatupperleftthai: "F896", - theharabic: "062B", - thehfinalarabic: "FE9A", - thehinitialarabic: "FE9B", - thehmedialarabic: "FE9C", - thereexists: "2203", - therefore: "2234", - theta: "03B8", - theta1: "03D1", - thetasymbolgreek: "03D1", - thieuthacirclekorean: "3279", - thieuthaparenkorean: "3219", - thieuthcirclekorean: "326B", - thieuthkorean: "314C", - thieuthparenkorean: "320B", - thirteencircle: "246C", - thirteenparen: "2480", - thirteenperiod: "2494", - thonangmonthothai: "0E11", - thook: "01AD", - thophuthaothai: "0E12", - thorn: "00FE", - thothahanthai: "0E17", - thothanthai: "0E10", - thothongthai: "0E18", - thothungthai: "0E16", - thousandcyrillic: "0482", - thousandsseparatorarabic: "066C", - thousandsseparatorpersian: "066C", - three: "0033", - threearabic: "0663", - threebengali: "09E9", - threecircle: "2462", - threecircleinversesansserif: "278C", - threedeva: "0969", - threeeighths: "215C", - threegujarati: "0AE9", - threegurmukhi: "0A69", - threehackarabic: "0663", - threehangzhou: "3023", - threeideographicparen: "3222", - threeinferior: "2083", - threemonospace: "FF13", - threenumeratorbengali: "09F6", - threeoldstyle: "F733", - threeparen: "2476", - threeperiod: "248A", - threepersian: "06F3", - threequarters: "00BE", - threequartersemdash: "F6DE", - threeroman: "2172", - threesuperior: "00B3", - threethai: "0E53", - thzsquare: "3394", - tihiragana: "3061", - tikatakana: "30C1", - tikatakanahalfwidth: "FF81", - tikeutacirclekorean: "3270", - tikeutaparenkorean: "3210", - tikeutcirclekorean: "3262", - tikeutkorean: "3137", - tikeutparenkorean: "3202", - tilde: "02DC", - tildebelowcmb: "0330", - tildecmb: "0303", - tildecomb: "0303", - tildedoublecmb: "0360", - tildeoperator: "223C", - tildeoverlaycmb: "0334", - tildeverticalcmb: "033E", - timescircle: "2297", - tipehahebrew: "0596", - tipehalefthebrew: "0596", - tippigurmukhi: "0A70", - titlocyrilliccmb: "0483", - tiwnarmenian: "057F", - tlinebelow: "1E6F", - tmonospace: "FF54", - toarmenian: "0569", - tohiragana: "3068", - tokatakana: "30C8", - tokatakanahalfwidth: "FF84", - tonebarextrahighmod: "02E5", - tonebarextralowmod: "02E9", - tonebarhighmod: "02E6", - tonebarlowmod: "02E8", - tonebarmidmod: "02E7", - tonefive: "01BD", - tonesix: "0185", - tonetwo: "01A8", - tonos: "0384", - tonsquare: "3327", - topatakthai: "0E0F", - tortoiseshellbracketleft: "3014", - tortoiseshellbracketleftsmall: "FE5D", - tortoiseshellbracketleftvertical: "FE39", - tortoiseshellbracketright: "3015", - tortoiseshellbracketrightsmall: "FE5E", - tortoiseshellbracketrightvertical: "FE3A", - totaothai: "0E15", - tpalatalhook: "01AB", - tparen: "24AF", - trademark: "2122", - trademarksans: "F8EA", - trademarkserif: "F6DB", - tretroflexhook: "0288", - triagdn: "25BC", - triaglf: "25C4", - triagrt: "25BA", - triagup: "25B2", - ts: "02A6", - tsadi: "05E6", - tsadidagesh: "FB46", - tsadidageshhebrew: "FB46", - tsadihebrew: "05E6", - tsecyrillic: "0446", - tsere: "05B5", - tsere12: "05B5", - tsere1e: "05B5", - tsere2b: "05B5", - tserehebrew: "05B5", - tserenarrowhebrew: "05B5", - tserequarterhebrew: "05B5", - tserewidehebrew: "05B5", - tshecyrillic: "045B", - tsuperior: "F6F3", - ttabengali: "099F", - ttadeva: "091F", - ttagujarati: "0A9F", - ttagurmukhi: "0A1F", - tteharabic: "0679", - ttehfinalarabic: "FB67", - ttehinitialarabic: "FB68", - ttehmedialarabic: "FB69", - tthabengali: "09A0", - tthadeva: "0920", - tthagujarati: "0AA0", - tthagurmukhi: "0A20", - tturned: "0287", - tuhiragana: "3064", - tukatakana: "30C4", - tukatakanahalfwidth: "FF82", - tusmallhiragana: "3063", - tusmallkatakana: "30C3", - tusmallkatakanahalfwidth: "FF6F", - twelvecircle: "246B", - twelveparen: "247F", - twelveperiod: "2493", - twelveroman: "217B", - twentycircle: "2473", - twentyhangzhou: "5344", - twentyparen: "2487", - twentyperiod: "249B", - two: "0032", - twoarabic: "0662", - twobengali: "09E8", - twocircle: "2461", - twocircleinversesansserif: "278B", - twodeva: "0968", - twodotenleader: "2025", - twodotleader: "2025", - twodotleadervertical: "FE30", - twogujarati: "0AE8", - twogurmukhi: "0A68", - twohackarabic: "0662", - twohangzhou: "3022", - twoideographicparen: "3221", - twoinferior: "2082", - twomonospace: "FF12", - twonumeratorbengali: "09F5", - twooldstyle: "F732", - twoparen: "2475", - twoperiod: "2489", - twopersian: "06F2", - tworoman: "2171", - twostroke: "01BB", - twosuperior: "00B2", - twothai: "0E52", - twothirds: "2154", - u: "0075", - uacute: "00FA", - ubar: "0289", - ubengali: "0989", - ubopomofo: "3128", - ubreve: "016D", - ucaron: "01D4", - ucircle: "24E4", - ucircumflex: "00FB", - ucircumflexbelow: "1E77", - ucyrillic: "0443", - udattadeva: "0951", - udblacute: "0171", - udblgrave: "0215", - udeva: "0909", - udieresis: "00FC", - udieresisacute: "01D8", - udieresisbelow: "1E73", - udieresiscaron: "01DA", - udieresiscyrillic: "04F1", - udieresisgrave: "01DC", - udieresismacron: "01D6", - udotbelow: "1EE5", - ugrave: "00F9", - ugujarati: "0A89", - ugurmukhi: "0A09", - uhiragana: "3046", - uhookabove: "1EE7", - uhorn: "01B0", - uhornacute: "1EE9", - uhorndotbelow: "1EF1", - uhorngrave: "1EEB", - uhornhookabove: "1EED", - uhorntilde: "1EEF", - uhungarumlaut: "0171", - uhungarumlautcyrillic: "04F3", - uinvertedbreve: "0217", - ukatakana: "30A6", - ukatakanahalfwidth: "FF73", - ukcyrillic: "0479", - ukorean: "315C", - umacron: "016B", - umacroncyrillic: "04EF", - umacrondieresis: "1E7B", - umatragurmukhi: "0A41", - umonospace: "FF55", - underscore: "005F", - underscoredbl: "2017", - underscoremonospace: "FF3F", - underscorevertical: "FE33", - underscorewavy: "FE4F", - union: "222A", - universal: "2200", - uogonek: "0173", - uparen: "24B0", - upblock: "2580", - upperdothebrew: "05C4", - upsilon: "03C5", - upsilondieresis: "03CB", - upsilondieresistonos: "03B0", - upsilonlatin: "028A", - upsilontonos: "03CD", - uptackbelowcmb: "031D", - uptackmod: "02D4", - uragurmukhi: "0A73", - uring: "016F", - ushortcyrillic: "045E", - usmallhiragana: "3045", - usmallkatakana: "30A5", - usmallkatakanahalfwidth: "FF69", - ustraightcyrillic: "04AF", - ustraightstrokecyrillic: "04B1", - utilde: "0169", - utildeacute: "1E79", - utildebelow: "1E75", - uubengali: "098A", - uudeva: "090A", - uugujarati: "0A8A", - uugurmukhi: "0A0A", - uumatragurmukhi: "0A42", - uuvowelsignbengali: "09C2", - uuvowelsigndeva: "0942", - uuvowelsigngujarati: "0AC2", - uvowelsignbengali: "09C1", - uvowelsigndeva: "0941", - uvowelsigngujarati: "0AC1", - v: "0076", - vadeva: "0935", - vagujarati: "0AB5", - vagurmukhi: "0A35", - vakatakana: "30F7", - vav: "05D5", - vavdagesh: "FB35", - vavdagesh65: "FB35", - vavdageshhebrew: "FB35", - vavhebrew: "05D5", - vavholam: "FB4B", - vavholamhebrew: "FB4B", - vavvavhebrew: "05F0", - vavyodhebrew: "05F1", - vcircle: "24E5", - vdotbelow: "1E7F", - vecyrillic: "0432", - veharabic: "06A4", - vehfinalarabic: "FB6B", - vehinitialarabic: "FB6C", - vehmedialarabic: "FB6D", - vekatakana: "30F9", - venus: "2640", - verticalbar: "007C", - verticallineabovecmb: "030D", - verticallinebelowcmb: "0329", - verticallinelowmod: "02CC", - verticallinemod: "02C8", - vewarmenian: "057E", - vhook: "028B", - vikatakana: "30F8", - viramabengali: "09CD", - viramadeva: "094D", - viramagujarati: "0ACD", - visargabengali: "0983", - visargadeva: "0903", - visargagujarati: "0A83", - vmonospace: "FF56", - voarmenian: "0578", - voicediterationhiragana: "309E", - voicediterationkatakana: "30FE", - voicedmarkkana: "309B", - voicedmarkkanahalfwidth: "FF9E", - vokatakana: "30FA", - vparen: "24B1", - vtilde: "1E7D", - vturned: "028C", - vuhiragana: "3094", - vukatakana: "30F4", - w: "0077", - wacute: "1E83", - waekorean: "3159", - wahiragana: "308F", - wakatakana: "30EF", - wakatakanahalfwidth: "FF9C", - wakorean: "3158", - wasmallhiragana: "308E", - wasmallkatakana: "30EE", - wattosquare: "3357", - wavedash: "301C", - wavyunderscorevertical: "FE34", - wawarabic: "0648", - wawfinalarabic: "FEEE", - wawhamzaabovearabic: "0624", - wawhamzaabovefinalarabic: "FE86", - wbsquare: "33DD", - wcircle: "24E6", - wcircumflex: "0175", - wdieresis: "1E85", - wdotaccent: "1E87", - wdotbelow: "1E89", - wehiragana: "3091", - weierstrass: "2118", - wekatakana: "30F1", - wekorean: "315E", - weokorean: "315D", - wgrave: "1E81", - whitebullet: "25E6", - whitecircle: "25CB", - whitecircleinverse: "25D9", - whitecornerbracketleft: "300E", - whitecornerbracketleftvertical: "FE43", - whitecornerbracketright: "300F", - whitecornerbracketrightvertical: "FE44", - whitediamond: "25C7", - whitediamondcontainingblacksmalldiamond: "25C8", - whitedownpointingsmalltriangle: "25BF", - whitedownpointingtriangle: "25BD", - whiteleftpointingsmalltriangle: "25C3", - whiteleftpointingtriangle: "25C1", - whitelenticularbracketleft: "3016", - whitelenticularbracketright: "3017", - whiterightpointingsmalltriangle: "25B9", - whiterightpointingtriangle: "25B7", - whitesmallsquare: "25AB", - whitesmilingface: "263A", - whitesquare: "25A1", - whitestar: "2606", - whitetelephone: "260F", - whitetortoiseshellbracketleft: "3018", - whitetortoiseshellbracketright: "3019", - whiteuppointingsmalltriangle: "25B5", - whiteuppointingtriangle: "25B3", - wihiragana: "3090", - wikatakana: "30F0", - wikorean: "315F", - wmonospace: "FF57", - wohiragana: "3092", - wokatakana: "30F2", - wokatakanahalfwidth: "FF66", - won: "20A9", - wonmonospace: "FFE6", - wowaenthai: "0E27", - wparen: "24B2", - wring: "1E98", - wsuperior: "02B7", - wturned: "028D", - wynn: "01BF", - x: "0078", - xabovecmb: "033D", - xbopomofo: "3112", - xcircle: "24E7", - xdieresis: "1E8D", - xdotaccent: "1E8B", - xeharmenian: "056D", - xi: "03BE", - xmonospace: "FF58", - xparen: "24B3", - xsuperior: "02E3", - y: "0079", - yaadosquare: "334E", - yabengali: "09AF", - yacute: "00FD", - yadeva: "092F", - yaekorean: "3152", - yagujarati: "0AAF", - yagurmukhi: "0A2F", - yahiragana: "3084", - yakatakana: "30E4", - yakatakanahalfwidth: "FF94", - yakorean: "3151", - yamakkanthai: "0E4E", - yasmallhiragana: "3083", - yasmallkatakana: "30E3", - yasmallkatakanahalfwidth: "FF6C", - yatcyrillic: "0463", - ycircle: "24E8", - ycircumflex: "0177", - ydieresis: "00FF", - ydotaccent: "1E8F", - ydotbelow: "1EF5", - yeharabic: "064A", - yehbarreearabic: "06D2", - yehbarreefinalarabic: "FBAF", - yehfinalarabic: "FEF2", - yehhamzaabovearabic: "0626", - yehhamzaabovefinalarabic: "FE8A", - yehhamzaaboveinitialarabic: "FE8B", - yehhamzaabovemedialarabic: "FE8C", - yehinitialarabic: "FEF3", - yehmedialarabic: "FEF4", - yehmeeminitialarabic: "FCDD", - yehmeemisolatedarabic: "FC58", - yehnoonfinalarabic: "FC94", - yehthreedotsbelowarabic: "06D1", - yekorean: "3156", - yen: "00A5", - yenmonospace: "FFE5", - yeokorean: "3155", - yeorinhieuhkorean: "3186", - yerahbenyomohebrew: "05AA", - yerahbenyomolefthebrew: "05AA", - yericyrillic: "044B", - yerudieresiscyrillic: "04F9", - yesieungkorean: "3181", - yesieungpansioskorean: "3183", - yesieungsioskorean: "3182", - yetivhebrew: "059A", - ygrave: "1EF3", - yhook: "01B4", - yhookabove: "1EF7", - yiarmenian: "0575", - yicyrillic: "0457", - yikorean: "3162", - yinyang: "262F", - yiwnarmenian: "0582", - ymonospace: "FF59", - yod: "05D9", - yoddagesh: "FB39", - yoddageshhebrew: "FB39", - yodhebrew: "05D9", - yodyodhebrew: "05F2", - yodyodpatahhebrew: "FB1F", - yohiragana: "3088", - yoikorean: "3189", - yokatakana: "30E8", - yokatakanahalfwidth: "FF96", - yokorean: "315B", - yosmallhiragana: "3087", - yosmallkatakana: "30E7", - yosmallkatakanahalfwidth: "FF6E", - yotgreek: "03F3", - yoyaekorean: "3188", - yoyakorean: "3187", - yoyakthai: "0E22", - yoyingthai: "0E0D", - yparen: "24B4", - ypogegrammeni: "037A", - ypogegrammenigreekcmb: "0345", - yr: "01A6", - yring: "1E99", - ysuperior: "02B8", - ytilde: "1EF9", - yturned: "028E", - yuhiragana: "3086", - yuikorean: "318C", - yukatakana: "30E6", - yukatakanahalfwidth: "FF95", - yukorean: "3160", - yusbigcyrillic: "046B", - yusbigiotifiedcyrillic: "046D", - yuslittlecyrillic: "0467", - yuslittleiotifiedcyrillic: "0469", - yusmallhiragana: "3085", - yusmallkatakana: "30E5", - yusmallkatakanahalfwidth: "FF6D", - yuyekorean: "318B", - yuyeokorean: "318A", - yyabengali: "09DF", - yyadeva: "095F", - z: "007A", - zaarmenian: "0566", - zacute: "017A", - zadeva: "095B", - zagurmukhi: "0A5B", - zaharabic: "0638", - zahfinalarabic: "FEC6", - zahinitialarabic: "FEC7", - zahiragana: "3056", - zahmedialarabic: "FEC8", - zainarabic: "0632", - zainfinalarabic: "FEB0", - zakatakana: "30B6", - zaqefgadolhebrew: "0595", - zaqefqatanhebrew: "0594", - zarqahebrew: "0598", - zayin: "05D6", - zayindagesh: "FB36", - zayindageshhebrew: "FB36", - zayinhebrew: "05D6", - zbopomofo: "3117", - zcaron: "017E", - zcircle: "24E9", - zcircumflex: "1E91", - zcurl: "0291", - zdot: "017C", - zdotaccent: "017C", - zdotbelow: "1E93", - zecyrillic: "0437", - zedescendercyrillic: "0499", - zedieresiscyrillic: "04DF", - zehiragana: "305C", - zekatakana: "30BC", - zero: "0030", - zeroarabic: "0660", - zerobengali: "09E6", - zerodeva: "0966", - zerogujarati: "0AE6", - zerogurmukhi: "0A66", - zerohackarabic: "0660", - zeroinferior: "2080", - zeromonospace: "FF10", - zerooldstyle: "F730", - zeropersian: "06F0", - zerosuperior: "2070", - zerothai: "0E50", - zerowidthjoiner: "FEFF", - zerowidthnonjoiner: "200C", - zerowidthspace: "200B", - zeta: "03B6", - zhbopomofo: "3113", - zhearmenian: "056A", - zhebrevecyrillic: "04C2", - zhecyrillic: "0436", - zhedescendercyrillic: "0497", - zhedieresiscyrillic: "04DD", - zihiragana: "3058", - zikatakana: "30B8", - zinorhebrew: "05AE", - zlinebelow: "1E95", - zmonospace: "FF5A", - zohiragana: "305E", - zokatakana: "30BE", - zparen: "24B5", - zretroflexhook: "0290", - zstroke: "01B6", - zuhiragana: "305A", - zukatakana: "30BA" + 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"] = "3008"; -GlyphsUnicode["angbracketright"] = "3009"; -GlyphsUnicode["circlecopyrt"] = "00A9"; +GlyphsUnicode["angbracketleft"] = 0x3008; +GlyphsUnicode["angbracketright"] = 0x3009; +GlyphsUnicode["circlecopyrt"] = 0x00A9; From b82392f41759b90a47fa6b6e67c913734ad28707 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 17 Jun 2011 01:19:59 -0700 Subject: [PATCH 77/77] render at 1.5x scale --- test.css | 4 ++-- test.html | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test.css b/test.css index 0a3449ae9..857eed101 100644 --- a/test.css +++ b/test.css @@ -26,8 +26,8 @@ span#info { #viewer { margin: auto; border: 1px solid black; - width: 8.5in; - height: 11in; + width: 12.75in; + height: 16.5in; } #pageNumber { diff --git a/test.html b/test.html index 023cdeec2..458c50268 100644 --- a/test.html +++ b/test.html @@ -26,8 +26,9 @@
- + are always 96 dpi. 816x1056 is 8.5x11in at 96dpi. --> + +