| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528 |
- var Typr = {};
- Typr["parse"] = function(buff)
- {
- var readFont = function(data, idx, offset,tmap) {
- var bin = Typr["B"];
-
- var T = Typr["T"];
- var prsr = {
- "cmap":T.cmap,
- "head":T.head,
- "hhea":T.hhea,
- "maxp":T.maxp,
- "hmtx":T.hmtx,
- "name":T.name,
- "OS/2":T.OS2,
- "post":T.post,
-
- "loca":T.loca,
- "kern":T.kern,
- "glyf":T.glyf,
-
- "CFF ":T.CFF,
- /*
- "GPOS",
- "GSUB",
- "GDEF",*/
- "CBLC":T.CBLC,
- "CBDT":T.CBDT,
-
- "SVG ":T.SVG,
- "COLR":T.colr,
- "CPAL":T.cpal,
- "sbix":T.sbix
- //"VORG",
- };
- var obj = {"_data":data, "_index":idx, "_offset":offset};
-
- for(var t in prsr) {
- var tab = Typr["findTable"](data, t, offset);
- if(tab) {
- var off=tab[0], tobj = tmap[off];
- if(tobj==null) tobj = prsr[t].parseTab(data, off, tab[1], obj);
- obj[t] = tmap[off] = tobj;
- }
- }
- return obj;
- }
-
-
- var bin = Typr["B"];
- var data = new Uint8Array(buff);
-
- var tmap = {};
- var tag = bin.readASCII(data, 0, 4);
- if(tag=="ttcf") {
- var offset = 4;
- var majV = bin.readUshort(data, offset); offset+=2;
- var minV = bin.readUshort(data, offset); offset+=2;
- var numF = bin.readUint (data, offset); offset+=4;
- var fnts = [];
- for(var i=0; i<numF; i++) {
- var foff = bin.readUint (data, offset); offset+=4;
- fnts.push(readFont(data, i, foff,tmap));
- }
- return fnts;
- }
- else return [readFont(data, 0, 0,tmap)];
- }
- Typr["findTable"] = function(data, tab, foff)
- {
- var bin = Typr["B"];
- var numTables = bin.readUshort(data, foff+4);
- var offset = foff+12;
- for(var i=0; i<numTables; i++)
- {
- var tag = bin.readASCII(data, offset, 4); //console.log(tag);
- var checkSum = bin.readUint (data, offset+ 4);
- var toffset = bin.readUint (data, offset+ 8);
- var length = bin.readUint (data, offset+12);
- if(tag==tab) return [toffset,length];
- offset+=16;
- }
- return null;
- }
- /*
- Typr["splitBy"] = function(data,tag) {
- data = new Uint8Array(data); console.log(data.slice(0,64));
- var bin = Typr["B"];
- var ttcf = bin.readASCII(data, 0, 4); if(ttcf!="ttcf") return {};
-
- var offset = 8;
- var numF = bin.readUint (data, offset); offset+=4;
- var colls = [], used={};
- for(var i=0; i<numF; i++) {
- var foff = bin.readUint (data, offset); offset+=4;
- var toff = Typr["findTable"](data,tag,foff)[0];
- if(used[toff]==null) used[toff] = [];
- used[toff].push([foff,bin.readUshort(data,foff+4)]); // font offset, numTables
- }
- for(var toff in used) {
- var offs = used[toff];
- var hlen = 12+4*offs.length;
- var out = new Uint8Array(hlen);
- for(var i=0; i<8; i++) out[i]=data[i];
- bin.writeUint(out,8,offs.length);
-
- for(var i=0; i<offs.length; i++) hlen += 12+offs[i][1]*16;
-
- var hdrs = [out], tabs = [], hoff=out.length, toff=hlen, noffs={};
- for(var i=0; i<offs.length; i++) {
- bin.writeUint(out, 12+i*4, hoff); hoff+=12+offs[i][1]*16;
- toff = Typr["_cutFont"](data, offs[i][0], hdrs, tabs, toff, noffs);
- }
- colls.push(Typr["_joinArrs"](hdrs.concat(tabs)));
- }
- return colls;
- }
- Typr["splitFonts"] = function(data) {
- data = new Uint8Array(data);
- var bin = Typr["B"];
- var ttcf = bin.readASCII(data, 0, 4); if(ttcf!="ttcf") return {};
-
- var offset = 8;
- var numF = bin.readUint (data, offset); offset+=4;
- var fnts = [];
- for(var i=0; i<numF; i++) {
- var foff = bin.readUint (data, offset); offset+=4;
- fnts.push(Typr._cutFont(data, foff));
- break;
- }
- return fnts;
- }
- Typr["_cutFont"] = function(data,foff,hdrs,tabs,toff, noffs) {
- var bin = Typr["B"];
- var numTables = bin.readUshort(data, foff+4);
-
- var out = new Uint8Array(12+numTables*16); hdrs.push(out);
- for(var i=0; i<12; i++) out[i]=data[foff+i]; //console.log(out);
-
- var off = 12;
- for(var i=0; i<numTables; i++)
- {
- var tag = bin.readASCII(data, foff+off, 4);
- var checkSum = bin.readUint (data, foff+off+ 4);
- var toffset = bin.readUint (data, foff+off+ 8);
- var length = bin.readUint (data, foff+off+12);
-
- while((length&3)!=0) length++;
-
- for(var j=0; j<16; j++) out[off+j]=data[foff+off+j];
-
- if(noffs[toffset]!=null) bin.writeUint(out,off+8,noffs[toffset]);
- else {
- noffs[toffset] = toff;
- bin.writeUint(out, off+8, toff);
- tabs.push(new Uint8Array(data.buffer, toffset, length)); toff+=length;
- }
- off+=16;
- }
- return toff;
- }
- Typr["_joinArrs"] = function(tabs) {
- var len = 0;
- for(var i=0; i<tabs.length; i++) len+=tabs[i].length;
- var out = new Uint8Array(len), ooff=0;
- for(var i=0; i<tabs.length; i++) {
- var tab = tabs[i];
- for(var j=0; j<tab.length; j++) out[ooff+j]=tab[j];
- ooff+=tab.length;
- }
- return out;
- }
- */
- Typr["T"]={};
- Typr["B"] = {
- readFixed : function(data, o)
- {
- return ((data[o]<<8) | data[o+1]) + (((data[o+2]<<8)|data[o+3])/(256*256+4));
- },
- readF2dot14 : function(data, o)
- {
- var num = Typr["B"].readShort(data, o);
- return num / 16384;
- },
- readInt : function(buff, p)
- {
- //if(p>=buff.length) throw "error";
- var a = Typr["B"].t.uint8;
- a[0] = buff[p+3];
- a[1] = buff[p+2];
- a[2] = buff[p+1];
- a[3] = buff[p];
- return Typr["B"].t.int32[0];
- },
-
- readInt8 : function(buff, p)
- {
- //if(p>=buff.length) throw "error";
- var a = Typr["B"].t.uint8;
- a[0] = buff[p];
- return Typr["B"].t.int8[0];
- },
- readShort : function(buff, p)
- {
- //if(p>=buff.length) throw "error";
- var a = Typr["B"].t.uint16;
- a[0] = (buff[p]<<8) | buff[p+1];
- return Typr["B"].t.int16[0];
- },
- readUshort : function(buff, p)
- {
- //if(p>=buff.length) throw "error";
- return (buff[p]<<8) | buff[p+1];
- },
- writeUshort : function(buff, p, n)
- {
- buff[p] = (n>>8)&255; buff[p+1] = n&255;
- },
- readUshorts : function(buff, p, len)
- {
- var arr = [];
- for(var i=0; i<len; i++) {
- var v = Typr["B"].readUshort(buff, p+i*2); //if(v==932) console.log(p+i*2);
- arr.push(v);
- }
- return arr;
- },
- readUint : function(buff, p)
- {
- //if(p>=buff.length) throw "error";
- var a = Typr["B"].t.uint8;
- a[3] = buff[p]; a[2] = buff[p+1]; a[1] = buff[p+2]; a[0] = buff[p+3];
- return Typr["B"].t.uint32[0];
- },
- writeUint: function(buff, p, n)
- {
- buff[p] = (n>>24)&255; buff[p+1] = (n>>16)&255; buff[p+2] = (n>>8)&255; buff[p+3] = (n>>0)&255;
- },
- readUint64 : function(buff, p)
- {
- //if(p>=buff.length) throw "error";
- return (Typr["B"].readUint(buff, p)*(0xffffffff+1)) + Typr["B"].readUint(buff, p+4);
- },
- readASCII : function(buff, p, l) // l : length in Characters (not Bytes)
- {
- //if(p>=buff.length) throw "error";
- var s = "";
- for(var i = 0; i < l; i++) s += String.fromCharCode(buff[p+i]);
- return s;
- },
- writeASCII : function(buff, p, s) // l : length in Characters (not Bytes)
- {
- for(var i = 0; i < s.length; i++)
- buff[p+i] = s.charCodeAt(i);
- },
- readUnicode : function(buff, p, l)
- {
- //if(p>=buff.length) throw "error";
- var s = "";
- for(var i = 0; i < l; i++)
- {
- var c = (buff[p++]<<8) | buff[p++];
- s += String.fromCharCode(c);
- }
- return s;
- },
- _tdec : window["TextDecoder"] ? new window["TextDecoder"]() : null,
- readUTF8 : function(buff, p, l) {
- var tdec = Typr["B"]._tdec;
- if(tdec && p==0 && l==buff.length) return tdec["decode"](buff);
- return Typr["B"].readASCII(buff,p,l);
- },
- readBytes : function(buff, p, l)
- {
- //if(p>=buff.length) throw "error";
- var arr = [];
- for(var i=0; i<l; i++) arr.push(buff[p+i]);
- return arr;
- },
- readASCIIArray : function(buff, p, l) // l : length in Characters (not Bytes)
- {
- //if(p>=buff.length) throw "error";
- var s = [];
- for(var i = 0; i < l; i++)
- s.push(String.fromCharCode(buff[p+i]));
- return s;
- },
- t : function() {
- var ab = new ArrayBuffer(8);
- return {
- buff : ab,
- int8 : new Int8Array (ab),
- uint8 : new Uint8Array (ab),
- int16 : new Int16Array (ab),
- uint16 : new Uint16Array(ab),
- int32 : new Int32Array (ab),
- uint32 : new Uint32Array(ab)
- }
- }()
- };
- Typr["T"].CFF = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var CFF = Typr["T"].CFF;
-
- data = new Uint8Array(data.buffer, offset, length);
- offset = 0;
-
- // Header
- var major = data[offset]; offset++;
- var minor = data[offset]; offset++;
- var hdrSize = data[offset]; offset++;
- var offsize = data[offset]; offset++;
- //console.log(major, minor, hdrSize, offsize);
-
- // Name INDEX
- var ninds = [];
- offset = CFF.readIndex(data, offset, ninds);
- var names = [];
-
- for(var i=0; i<ninds.length-1; i++) names.push(bin.readASCII(data, offset+ninds[i], ninds[i+1]-ninds[i]));
- offset += ninds[ninds.length-1];
-
-
- // Top DICT INDEX
- var tdinds = [];
- offset = CFF.readIndex(data, offset, tdinds); //console.log(tdinds);
- // Top DICT Data
- var topDicts = [];
- for(var i=0; i<tdinds.length-1; i++) topDicts.push( CFF.readDict(data, offset+tdinds[i], offset+tdinds[i+1]) );
- offset += tdinds[tdinds.length-1];
- var topdict = topDicts[0];
- //console.log(topdict);
-
- // String INDEX
- var sinds = [];
- offset = CFF.readIndex(data, offset, sinds);
- // String Data
- var strings = [];
- for(var i=0; i<sinds.length-1; i++) strings.push(bin.readASCII(data, offset+sinds[i], sinds[i+1]-sinds[i]));
- offset += sinds[sinds.length-1];
-
- // Global Subr INDEX (subroutines)
- CFF.readSubrs(data, offset, topdict);
-
- // charstrings
-
- if(topdict["CharStrings"]) topdict["CharStrings"] = CFF.readBytes(data, topdict["CharStrings"]);
-
- // CID font
- if(topdict["ROS"]) {
- offset = topdict["FDArray"];
- var fdind = [];
- offset = CFF.readIndex(data, offset, fdind);
-
- topdict["FDArray"] = [];
- for(var i=0; i<fdind.length-1; i++) {
- var dict = CFF.readDict(data, offset+fdind[i], offset+fdind[i+1]);
- CFF._readFDict(data, dict, strings);
- topdict["FDArray"].push( dict );
- }
- offset += fdind[fdind.length-1];
-
- offset = topdict["FDSelect"];
- topdict["FDSelect"] = [];
- var fmt = data[offset]; offset++;
- if(fmt==3) {
- var rns = bin.readUshort(data, offset); offset+=2;
- for(var i=0; i<rns+1; i++) {
- topdict["FDSelect"].push(bin.readUshort(data, offset), data[offset+2]); offset+=3;
- }
- }
- else throw fmt;
- }
-
- // Encoding
- //if(topdict["Encoding"]) topdict["Encoding"] = CFF.readEncoding(data, topdict["Encoding"], topdict["CharStrings"].length);
-
- // charset
- if(topdict["charset"] ) topdict["charset"] = CFF.readCharset (data, topdict["charset"] , topdict["CharStrings"].length);
-
- CFF._readFDict(data, topdict, strings);
- return topdict;
- },
-
- _readFDict : function(data, dict, ss) {
- var CFF = Typr["T"].CFF;
- var offset;
- if(dict["Private"]) {
- offset = dict["Private"][1];
- dict["Private"] = CFF.readDict(data, offset, offset+dict["Private"][0]);
- if(dict["Private"]["Subrs"]) CFF.readSubrs(data, offset+dict["Private"]["Subrs"], dict["Private"]);
- }
- for(var p in dict) if(["FamilyName","FontName","FullName","Notice","version","Copyright"].indexOf(p)!=-1) dict[p]=ss[dict[p] -426 + 35];
- },
-
- readSubrs : function(data, offset, obj)
- {
- obj["Subrs"] = Typr["T"].CFF.readBytes(data, offset);
-
- var bias, nSubrs = obj["Subrs"].length+1;
- if (false) bias = 0;
- else if (nSubrs < 1240) bias = 107;
- else if (nSubrs < 33900) bias = 1131;
- else bias = 32768;
- obj["Bias"] = bias;
- },
- readBytes : function(data, offset) {
- var bin = Typr["B"];
- var arr = [];
- offset = Typr["T"].CFF.readIndex(data, offset, arr);
-
- var subrs = [], arl = arr.length-1, no = data.byteOffset+offset;
- for(var i=0; i<arl; i++) {
- var ari = arr[i];
- subrs.push(new Uint8Array(data.buffer, no+ari, arr[i+1]-ari));
- }
- return subrs;
- },
-
- tableSE : [
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 95, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 96, 97, 98, 99, 100, 101, 102,
- 103, 104, 105, 106, 107, 108, 109, 110,
- 0, 111, 112, 113, 114, 0, 115, 116,
- 117, 118, 119, 120, 121, 122, 0, 123,
- 0, 124, 125, 126, 127, 128, 129, 130,
- 131, 0, 132, 133, 0, 134, 135, 136,
- 137, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 138, 0, 139, 0, 0, 0, 0,
- 140, 141, 142, 143, 0, 0, 0, 0,
- 0, 144, 0, 0, 0, 145, 0, 0,
- 146, 147, 148, 149, 0, 0, 0, 0
- ],
-
- glyphByUnicode : function(cff, code)
- {
- for(var i=0; i<cff["charset"].length; i++) if(cff["charset"][i]==code) return i;
- return -1;
- },
-
- glyphBySE : function(cff, charcode) // glyph by standard encoding
- {
- if ( charcode < 0 || charcode > 255 ) return -1;
- return Typr["T"].CFF.glyphByUnicode(cff, Typr["T"].CFF.tableSE[charcode]);
- },
-
- /*readEncoding : function(data, offset, num)
- {
- var bin = Typr["B"];
-
- var array = ['.notdef'];
- var format = data[offset]; offset++;
- //console.log("Encoding");
- //console.log(format);
-
- if(format==0)
- {
- var nCodes = data[offset]; offset++;
- for(var i=0; i<nCodes; i++) array.push(data[offset+i]);
- }
- /*
- else if(format==1 || format==2)
- {
- while(charset.length<num)
- {
- var first = bin.readUshort(data, offset); offset+=2;
- var nLeft=0;
- if(format==1) { nLeft = data[offset]; offset++; }
- else { nLeft = bin.readUshort(data, offset); offset+=2; }
- for(var i=0; i<=nLeft; i++) { charset.push(first); first++; }
- }
- }
-
- else throw "error: unknown encoding format: " + format;
-
- return array;
- },*/
- readCharset : function(data, offset, num)
- {
- var bin = Typr["B"];
-
- var charset = ['.notdef'];
- var format = data[offset]; offset++;
-
- if(format==0)
- {
- for(var i=0; i<num; i++)
- {
- var first = bin.readUshort(data, offset); offset+=2;
- charset.push(first);
- }
- }
- else if(format==1 || format==2)
- {
- while(charset.length<num)
- {
- var first = bin.readUshort(data, offset); offset+=2;
- var nLeft=0;
- if(format==1) { nLeft = data[offset]; offset++; }
- else { nLeft = bin.readUshort(data, offset); offset+=2; }
- for(var i=0; i<=nLeft; i++) { charset.push(first); first++; }
- }
- }
- else throw "error: format: " + format;
-
- return charset;
- },
- readIndex : function(data, offset, inds)
- {
- var bin = Typr["B"];
-
- var count = bin.readUshort(data, offset)+1; offset+=2;
- var offsize = data[offset]; offset++;
-
- if (offsize==1) for(var i=0; i<count; i++) inds.push( data[offset+i] );
- else if(offsize==2) for(var i=0; i<count; i++) inds.push( bin.readUshort(data, offset+i*2) );
- else if(offsize==3) for(var i=0; i<count; i++) inds.push( bin.readUint (data, offset+i*3 - 1) & 0x00ffffff );
- else if(offsize==4) for(var i=0; i<count; i++) inds.push( bin.readUint (data, offset+i*4) );
- else if(count!=1) throw "unsupported offset size: " + offsize + ", count: " + count;
-
- offset += count*offsize;
- return offset-1;
- },
-
- getCharString : function(data, offset, o)
- {
- var bin = Typr["B"];
-
- var b0 = data[offset], b1 = data[offset+1], b2 = data[offset+2], b3 = data[offset+3], b4=data[offset+4];
- var vs = 1;
- var op=null, val=null;
- // operand
- if(b0<=20) { op = b0; vs=1; }
- if(b0==12) { op = b0*100+b1; vs=2; }
- //if(b0==19 || b0==20) { op = b0/*+" "+b1*/; vs=2; }
- if(21 <=b0 && b0<= 27) { op = b0; vs=1; }
- if(b0==28) { val = bin.readShort(data,offset+1); vs=3; }
- if(29 <=b0 && b0<= 31) { op = b0; vs=1; }
- if(32 <=b0 && b0<=246) { val = b0-139; vs=1; }
- if(247<=b0 && b0<=250) { val = (b0-247)*256+b1+108; vs=2; }
- if(251<=b0 && b0<=254) { val =-(b0-251)*256-b1-108; vs=2; }
- if(b0==255) { val = bin.readInt(data, offset+1)/0xffff; vs=5; }
-
- o.val = val!=null ? val : "o"+op;
- o.size = vs;
- },
-
- readCharString : function(data, offset, length)
- {
- var end = offset + length;
- var bin = Typr["B"];
- var arr = [];
-
- while(offset<end)
- {
- var b0 = data[offset], b1 = data[offset+1], b2 = data[offset+2], b3 = data[offset+3], b4=data[offset+4];
- var vs = 1;
- var op=null, val=null;
- // operand
- if(b0<=20) { op = b0; vs=1; }
- if(b0==12) { op = b0*100+b1; vs=2; }
- if(b0==19 || b0==20) { op = b0/*+" "+b1*/; vs=2; }
- if(21 <=b0 && b0<= 27) { op = b0; vs=1; }
- if(b0==28) { val = bin.readShort(data,offset+1); vs=3; }
- if(29 <=b0 && b0<= 31) { op = b0; vs=1; }
- if(32 <=b0 && b0<=246) { val = b0-139; vs=1; }
- if(247<=b0 && b0<=250) { val = (b0-247)*256+b1+108; vs=2; }
- if(251<=b0 && b0<=254) { val =-(b0-251)*256-b1-108; vs=2; }
- if(b0==255) { val = bin.readInt(data, offset+1)/0xffff; vs=5; }
-
- arr.push(val!=null ? val : "o"+op);
- offset += vs;
- //var cv = arr[arr.length-1];
- //if(cv==undefined) throw "error";
- //console.log()
- }
- return arr;
- },
- readDict : function(data, offset, end)
- {
- var bin = Typr["B"];
- //var dict = [];
- var dict = {};
- var carr = [];
-
- while(offset<end)
- {
- var b0 = data[offset], b1 = data[offset+1], b2 = data[offset+2], b3 = data[offset+3], b4=data[offset+4];
- var vs = 1;
- var key=null, val=null;
- // operand
- if(b0==28) { val = bin.readShort(data,offset+1); vs=3; }
- if(b0==29) { val = bin.readInt (data,offset+1); vs=5; }
- if(32 <=b0 && b0<=246) { val = b0-139; vs=1; }
- if(247<=b0 && b0<=250) { val = (b0-247)*256+b1+108; vs=2; }
- if(251<=b0 && b0<=254) { val =-(b0-251)*256-b1-108; vs=2; }
- if(b0==255) { val = bin.readInt(data, offset+1)/0xffff; vs=5; throw "unknown number"; }
-
- if(b0==30)
- {
- var nibs = [];
- vs = 1;
- while(true)
- {
- var b = data[offset+vs]; vs++;
- var nib0 = b>>4, nib1 = b&0xf;
- if(nib0 != 0xf) nibs.push(nib0); if(nib1!=0xf) nibs.push(nib1);
- if(nib1==0xf) break;
- }
- var s = "";
- var chars = [0,1,2,3,4,5,6,7,8,9,".","e","e-","reserved","-","endOfNumber"];
- for(var i=0; i<nibs.length; i++) s += chars[nibs[i]];
- //console.log(nibs);
- val = parseFloat(s);
- }
-
- if(b0<=21) // operator
- {
- var keys = ["version", "Notice", "FullName", "FamilyName", "Weight", "FontBBox", "BlueValues", "OtherBlues", "FamilyBlues","FamilyOtherBlues",
- "StdHW", "StdVW", "escape", "UniqueID", "XUID", "charset", "Encoding", "CharStrings", "Private", "Subrs",
- "defaultWidthX", "nominalWidthX"];
-
- key = keys[b0]; vs=1;
- if(b0==12) {
- var keys = [ "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", "StrokeWidth", "BlueScale",
- "BlueShift", "BlueFuzz", "StemSnapH", "StemSnapV", "ForceBold", "","", "LanguageGroup", "ExpansionFactor", "initialRandomSeed",
- "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", "","","", "","","",
- "ROS", "CIDFontVersion", "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", "FDArray", "FDSelect", "FontName"];
- key = keys[b1]; vs=2;
- }
- }
-
- if(key!=null) { dict[key] = carr.length==1 ? carr[0] : carr; carr=[]; }
- else carr.push(val);
-
- offset += vs;
- }
- return dict;
- }
- };
- Typr["T"].cmap = {
- parseTab : function(data, offset, length)
- {
- var obj = {tables:[],ids:{},off:offset};
- data = new Uint8Array(data.buffer, offset, length);
- offset = 0;
- var offset0 = offset;
- var bin = Typr["B"], rU = bin.readUshort, cmap = Typr["T"].cmap;
- var version = rU(data, offset); offset += 2;
- var numTables = rU(data, offset); offset += 2;
-
- //console.log(version, numTables);
-
- var offs = [];
-
-
- for(var i=0; i<numTables; i++)
- {
- var platformID = rU(data, offset); offset += 2;
- var encodingID = rU(data, offset); offset += 2;
- var noffset = bin.readUint(data, offset); offset += 4;
-
- var id = "p"+platformID+"e"+encodingID;
-
- //console.log("cmap subtable", platformID, encodingID, noffset);
-
-
- var tind = offs.indexOf(noffset);
-
- if(tind==-1)
- {
- tind = obj.tables.length;
- var subt = {};
- offs.push(noffset);
- //var time = Date.now();
- var format = subt.format = rU(data, noffset);
- if (format== 0) subt = cmap.parse0(data, noffset, subt);
- //else if(format== 2) subt.off = noffset;
- else if(format== 4) subt = cmap.parse4(data, noffset, subt);
- else if(format== 6) subt = cmap.parse6(data, noffset, subt);
- else if(format==12) subt = cmap.parse12(data,noffset, subt);
- //console.log(format, Date.now()-time);
- //else console.log("unknown format: "+format, platformID, encodingID, noffset);
- obj.tables.push(subt);
- }
-
- if(obj.ids[id]!=null) console.log("multiple tables for one platform+encoding: "+id);
- obj.ids[id] = tind;
- }
- return obj;
- },
- parse0 : function(data, offset, obj)
- {
- var bin = Typr["B"];
- offset += 2;
- var len = bin.readUshort(data, offset); offset += 2;
- var lang = bin.readUshort(data, offset); offset += 2;
- obj.map = [];
- for(var i=0; i<len-6; i++) obj.map.push(data[offset+i]);
- return obj;
- },
- parse4 : function(data, offset, obj)
- {
- var bin = Typr["B"], rU = bin.readUshort, rUs = bin.readUshorts;
- var offset0 = offset;
- offset+=2;
- var length = rU(data, offset); offset+=2;
- var language = rU(data, offset); offset+=2;
- var segCountX2 = rU(data, offset); offset+=2;
- var segCount = segCountX2>>>1;
- obj.searchRange = rU(data, offset); offset+=2;
- obj.entrySelector = rU(data, offset); offset+=2;
- obj.rangeShift = rU(data, offset); offset+=2;
- obj.endCount = rUs(data, offset, segCount); offset += segCount*2;
- offset+=2;
- obj.startCount = rUs(data, offset, segCount); offset += segCount*2;
- obj.idDelta = [];
- for(var i=0; i<segCount; i++) {obj.idDelta.push(bin.readShort(data, offset)); offset+=2;}
- obj.idRangeOffset = rUs(data, offset, segCount); offset += segCount*2;
- obj.glyphIdArray = rUs(data, offset, ((offset0+length)-offset)>>>1); //offset += segCount*2;
- return obj;
- },
- parse6 : function(data, offset, obj)
- {
- var bin = Typr["B"];
- var offset0 = offset;
- offset+=2;
- var length = bin.readUshort(data, offset); offset+=2;
- var language = bin.readUshort(data, offset); offset+=2;
- obj.firstCode = bin.readUshort(data, offset); offset+=2;
- var entryCount = bin.readUshort(data, offset); offset+=2;
- obj.glyphIdArray = [];
- for(var i=0; i<entryCount; i++) {obj.glyphIdArray.push(bin.readUshort(data, offset)); offset+=2;}
-
- return obj;
- },
- parse12 : function(data, offset, obj)
- {
- var bin = Typr["B"], rU = bin.readUint;
- var offset0 = offset;
- offset+=4;
- var length = rU(data, offset); offset+=4;
- var lang = rU(data, offset); offset+=4;
- var nGroups= rU(data, offset)*3; offset+=4;
-
- var gps = obj.groups = new Uint32Array(nGroups);//new Uint32Array(data.slice(offset, offset+nGroups*12).buffer);
-
- for(var i=0; i<nGroups; i+=3) {
- gps[i ] = rU(data, offset+(i<<2) );
- gps[i+1] = rU(data, offset+(i<<2)+4);
- gps[i+2] = rU(data, offset+(i<<2)+8);
- }
- return obj;
- }
- };
- Typr["T"].CBLC = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"], ooff=offset;
-
- var maj = bin.readUshort(data,offset); offset+=2;
- var min = bin.readUshort(data,offset); offset+=2;
-
- var numSizes = bin.readUint (data,offset); offset+=4;
-
- var out = [];
- for(var i=0; i<numSizes; i++) {
- var off = bin.readUint (data,offset); offset+=4; // indexSubTableArrayOffset
- var siz = bin.readUint (data,offset); offset+=4; // indexTablesSize
- var num = bin.readUint (data,offset); offset+=4; // numberOfIndexSubTables
- offset+=4;
-
- offset+=2*12;
-
- var sGlyph = bin.readUshort(data,offset); offset+=2;
- var eGlyph = bin.readUshort(data,offset); offset+=2;
-
- //console.log(off,siz,num, sGlyph, eGlyph);
-
- offset+=4;
-
- var coff = ooff+off;
- for(var j=0; j<3; j++) {
- var fgI = bin.readUshort(data,coff); coff+=2;
- var lgI = bin.readUshort(data,coff); coff+=2;
- var nxt = bin.readUint (data,coff); coff+=4;
- var gcnt = lgI-fgI+1;
- //console.log(fgI, lgI, nxt); //if(nxt==0) break;
-
- var ioff = ooff+off+nxt;
-
- var inF = bin.readUshort(data,ioff); ioff+=2; if(inF!=1) throw inF;
- var imF = bin.readUshort(data,ioff); ioff+=2;
- var imgo = bin.readUint (data,ioff); ioff+=4;
-
- var oarr = [];
- for(var gi=0; gi<gcnt; gi++) {
- var sbitO = bin.readUint(data,ioff+gi*4); oarr.push(imgo+sbitO);
- //console.log("--",sbitO);
- }
- out.push([fgI,lgI,imF,oarr]);
- }
- }
- return out;
- }
- };
- Typr["T"].CBDT = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var ooff=offset;
-
- //var maj = bin.readUshort(data,offset); offset+=2;
- //var min = bin.readUshort(data,offset); offset+=2;
-
- return new Uint8Array(data.buffer, data.byteOffset+offset, length);
- }
- };
- Typr["T"].glyf = {
- parseTab : function(data, offset, length, font)
- {
- var obj = [], ng=font["maxp"]["numGlyphs"];
- for(var g=0; g<ng; g++) obj.push(null);
- return obj;
- },
- _parseGlyf : function(font, g)
- {
- var bin = Typr["B"];
- var data = font["_data"], loca=font["loca"];
-
- if(loca[g]==loca[g+1]) return null;
-
- var offset = Typr["findTable"](data, "glyf", font["_offset"])[0] + loca[g];
-
- var gl = {};
-
- gl.noc = bin.readShort(data, offset); offset+=2; // number of contours
- gl.xMin = bin.readShort(data, offset); offset+=2;
- gl.yMin = bin.readShort(data, offset); offset+=2;
- gl.xMax = bin.readShort(data, offset); offset+=2;
- gl.yMax = bin.readShort(data, offset); offset+=2;
-
- if(gl.xMin>=gl.xMax || gl.yMin>=gl.yMax) return null;
-
- if(gl.noc>0)
- {
- gl.endPts = [];
- for(var i=0; i<gl.noc; i++) { gl.endPts.push(bin.readUshort(data,offset)); offset+=2; }
-
- var instructionLength = bin.readUshort(data,offset); offset+=2;
- if((data.length-offset)<instructionLength) return null;
- gl.instructions = bin.readBytes(data, offset, instructionLength); offset+=instructionLength;
-
- var crdnum = gl.endPts[gl.noc-1]+1;
- gl.flags = [];
- for(var i=0; i<crdnum; i++ )
- {
- var flag = data[offset]; offset++;
- gl.flags.push(flag);
- if((flag&8)!=0)
- {
- var rep = data[offset]; offset++;
- for(var j=0; j<rep; j++) { gl.flags.push(flag); i++; }
- }
- }
- gl.xs = [];
- for(var i=0; i<crdnum; i++) {
- var i8=((gl.flags[i]&2)!=0), same=((gl.flags[i]&16)!=0);
- if(i8) { gl.xs.push(same ? data[offset] : -data[offset]); offset++; }
- else
- {
- if(same) gl.xs.push(0);
- else { gl.xs.push(bin.readShort(data, offset)); offset+=2; }
- }
- }
- gl.ys = [];
- for(var i=0; i<crdnum; i++) {
- var i8=((gl.flags[i]&4)!=0), same=((gl.flags[i]&32)!=0);
- if(i8) { gl.ys.push(same ? data[offset] : -data[offset]); offset++; }
- else
- {
- if(same) gl.ys.push(0);
- else { gl.ys.push(bin.readShort(data, offset)); offset+=2; }
- }
- }
- var x = 0, y = 0;
- for(var i=0; i<crdnum; i++) { x += gl.xs[i]; y += gl.ys[i]; gl.xs[i]=x; gl.ys[i]=y; }
- //console.log(endPtsOfContours, instructionLength, instructions, flags, xCoordinates, yCoordinates);
- }
- else
- {
- var ARG_1_AND_2_ARE_WORDS = 1<<0;
- var ARGS_ARE_XY_VALUES = 1<<1;
- var ROUND_XY_TO_GRID = 1<<2;
- var WE_HAVE_A_SCALE = 1<<3;
- var RESERVED = 1<<4;
- var MORE_COMPONENTS = 1<<5;
- var WE_HAVE_AN_X_AND_Y_SCALE= 1<<6;
- var WE_HAVE_A_TWO_BY_TWO = 1<<7;
- var WE_HAVE_INSTRUCTIONS = 1<<8;
- var USE_MY_METRICS = 1<<9;
- var OVERLAP_COMPOUND = 1<<10;
- var SCALED_COMPONENT_OFFSET = 1<<11;
- var UNSCALED_COMPONENT_OFFSET = 1<<12;
-
- gl.parts = [];
- var flags;
- do {
- flags = bin.readUshort(data, offset); offset += 2;
- var part = { m:{a:1,b:0,c:0,d:1,tx:0,ty:0}, p1:-1, p2:-1 }; gl.parts.push(part);
- part.glyphIndex = bin.readUshort(data, offset); offset += 2;
- if ( flags & ARG_1_AND_2_ARE_WORDS) {
- var arg1 = bin.readShort(data, offset); offset += 2;
- var arg2 = bin.readShort(data, offset); offset += 2;
- } else {
- var arg1 = bin.readInt8(data, offset); offset ++;
- var arg2 = bin.readInt8(data, offset); offset ++;
- }
-
- if(flags & ARGS_ARE_XY_VALUES) { part.m.tx = arg1; part.m.ty = arg2; }
- else { part.p1=arg1; part.p2=arg2; }
- //part.m.tx = arg1; part.m.ty = arg2;
- //else { throw "params are not XY values"; }
-
- if ( flags & WE_HAVE_A_SCALE ) {
- part.m.a = part.m.d = bin.readF2dot14(data, offset); offset += 2;
- } else if ( flags & WE_HAVE_AN_X_AND_Y_SCALE ) {
- part.m.a = bin.readF2dot14(data, offset); offset += 2;
- part.m.d = bin.readF2dot14(data, offset); offset += 2;
- } else if ( flags & WE_HAVE_A_TWO_BY_TWO ) {
- part.m.a = bin.readF2dot14(data, offset); offset += 2;
- part.m.b = bin.readF2dot14(data, offset); offset += 2;
- part.m.c = bin.readF2dot14(data, offset); offset += 2;
- part.m.d = bin.readF2dot14(data, offset); offset += 2;
- }
- } while ( flags & MORE_COMPONENTS )
- if (flags & WE_HAVE_INSTRUCTIONS){
- var numInstr = bin.readUshort(data, offset); offset += 2;
- gl.instr = [];
- for(var i=0; i<numInstr; i++) { gl.instr.push(data[offset]); offset++; }
- }
- }
- return gl;
- }
- };
- Typr["T"].head = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var obj = {};
- var tableVersion = bin.readFixed(data, offset); offset += 4;
-
- obj["fontRevision"] = bin.readFixed(data, offset); offset += 4;
- var checkSumAdjustment = bin.readUint(data, offset); offset += 4;
- var magicNumber = bin.readUint(data, offset); offset += 4;
- obj["flags"] = bin.readUshort(data, offset); offset += 2;
- obj["unitsPerEm"] = bin.readUshort(data, offset); offset += 2;
- obj["created"] = bin.readUint64(data, offset); offset += 8;
- obj["modified"] = bin.readUint64(data, offset); offset += 8;
- obj["xMin"] = bin.readShort(data, offset); offset += 2;
- obj["yMin"] = bin.readShort(data, offset); offset += 2;
- obj["xMax"] = bin.readShort(data, offset); offset += 2;
- obj["yMax"] = bin.readShort(data, offset); offset += 2;
- obj["macStyle"] = bin.readUshort(data, offset); offset += 2;
- obj["lowestRecPPEM"] = bin.readUshort(data, offset); offset += 2;
- obj["fontDirectionHint"] = bin.readShort(data, offset); offset += 2;
- obj["indexToLocFormat"] = bin.readShort(data, offset); offset += 2;
- obj["glyphDataFormat"] = bin.readShort(data, offset); offset += 2;
- return obj;
- }
- };
- Typr["T"].hhea = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var obj = {};
- var tableVersion = bin.readFixed(data, offset); offset += 4;
-
- var keys = ["ascender","descender","lineGap",
- "advanceWidthMax","minLeftSideBearing","minRightSideBearing","xMaxExtent",
- "caretSlopeRise","caretSlopeRun","caretOffset",
- "res0","res1","res2","res3",
- "metricDataFormat","numberOfHMetrics" ];
-
- for(var i=0; i< keys.length; i++) {
- var key = keys[i];
- var func = (key=="advanceWidthMax" || key=="numberOfHMetrics")?bin.readUshort:bin.readShort;
- obj[key]=func(data,offset+i*2);
- }
- return obj;
- }
- };
- Typr["T"].hmtx = {
- parseTab : function(data, offset, length, font)
- {
- var bin = Typr["B"];
- var aWidth = [];
- var lsBearing = [];
-
- var nG = font["maxp"]["numGlyphs"], nH = font["hhea"]["numberOfHMetrics"];
- var aw = 0, lsb = 0, i=0;
- while(i<nH) { aw=bin.readUshort(data, offset+(i<<2)); lsb=bin.readShort(data, offset+(i<<2)+2); aWidth.push(aw); lsBearing.push(lsb); i++; }
- while(i<nG) { aWidth.push(aw); lsBearing.push(lsb); i++; }
-
- return {aWidth:aWidth, lsBearing:lsBearing};
- }
- };
- Typr["T"].kern = {
- parseTab : function(data, offset, length, font)
- {
- var bin = Typr["B"], kern=Typr["T"].kern;
-
- var version = bin.readUshort(data, offset);
- if(version==1) return kern.parseV1(data, offset, length, font);
- var nTables = bin.readUshort(data, offset+2); offset+=4;
-
- var map = {glyph1: [], rval:[]};
- for(var i=0; i<nTables; i++)
- {
- offset+=2; // skip version
- var length = bin.readUshort(data, offset); offset+=2;
- var coverage = bin.readUshort(data, offset); offset+=2;
- var format = coverage>>>8;
- /* I have seen format 128 once, that's why I do */ format &= 0xf;
- if(format==0) offset = kern.readFormat0(data, offset, map);
- //else throw "unknown kern table format: "+format;
- }
- return map;
- },
- parseV1 : function(data, offset, length, font)
- {
- var bin = Typr["B"], kern=Typr["T"].kern;
-
- var version = bin.readFixed(data, offset); // 0x00010000
- var nTables = bin.readUint (data, offset+4); offset+=8;
-
- var map = {glyph1: [], rval:[]};
- for(var i=0; i<nTables; i++)
- {
- var length = bin.readUint(data, offset); offset+=4;
- var coverage = bin.readUshort(data, offset); offset+=2;
- var tupleIndex = bin.readUshort(data, offset); offset+=2;
- var format = coverage&0xff;
- if(format==0) offset = kern.readFormat0(data, offset, map);
- //else throw "unknown kern table format: "+format;
- }
- return map;
- },
- readFormat0 : function(data, offset, map)
- {
- var bin = Typr["B"], rUs = bin.readUshort;
- var pleft = -1;
- var nPairs = rUs(data, offset);
- var searchRange = rUs(data, offset+2);
- var entrySelector = rUs(data, offset+4);
- var rangeShift = rUs(data, offset+6); offset+=8;
- for(var j=0; j<nPairs; j++)
- {
- var left = rUs(data, offset); offset+=2;
- var right = rUs(data, offset); offset+=2;
- var value = bin.readShort (data, offset); offset+=2;
- if(left!=pleft) { map.glyph1.push(left); map.rval.push({ glyph2:[], vals:[] }) }
- var rval = map.rval[map.rval.length-1];
- rval.glyph2.push(right); rval.vals.push(value);
- pleft = left;
- }
- return offset;
- }
- };
- Typr["T"].loca = {
- parseTab : function(data, offset, length, font)
- {
- var bin = Typr["B"];
- var obj = [];
-
- var ver = font["head"]["indexToLocFormat"];
- var len = font["maxp"]["numGlyphs"]+1;
-
- if(ver==0) for(var i=0; i<len; i++) obj.push(bin.readUshort(data, offset+(i<<1))<<1);
- if(ver==1) for(var i=0; i<len; i++) obj.push(bin.readUint (data, offset+(i<<2)) );
-
- return obj;
- }
- };
- Typr["T"].maxp = {
- parseTab : function(data, offset, length)
- {
- //console.log(data.length, offset, length);
-
- var bin = Typr["B"], rU=bin.readUshort;
- var obj = {};
-
- // both versions 0.5 and 1.0
- var ver = bin.readUint(data, offset); offset += 4;
-
- obj["numGlyphs"] = rU(data, offset); offset += 2;
-
- // only 1.0
- /*
- if(ver == 0x00010000) {
- obj.maxPoints = rU(data, offset); offset += 2;
- obj.maxContours = rU(data, offset); offset += 2;
- obj.maxCompositePoints = rU(data, offset); offset += 2;
- obj.maxCompositeContours = rU(data, offset); offset += 2;
- obj.maxZones = rU(data, offset); offset += 2;
- obj.maxTwilightPoints = rU(data, offset); offset += 2;
- obj.maxStorage = rU(data, offset); offset += 2;
- obj.maxFunctionDefs = rU(data, offset); offset += 2;
- obj.maxInstructionDefs = rU(data, offset); offset += 2;
- obj.maxStackElements = rU(data, offset); offset += 2;
- obj.maxSizeOfInstructions = rU(data, offset); offset += 2;
- obj.maxComponentElements = rU(data, offset); offset += 2;
- obj.maxComponentDepth = rU(data, offset); offset += 2;
- }
- */
-
- return obj;
- }
- };
- Typr["T"].name = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var obj = {};
- var format = bin.readUshort(data, offset); offset += 2;
- var count = bin.readUshort(data, offset); offset += 2;
- var stringOffset = bin.readUshort(data, offset); offset += 2;
-
- //console.log(format,count);
-
- var names = [
- "copyright",
- "fontFamily",
- "fontSubfamily",
- "ID",
- "fullName",
- "version",
- "postScriptName",
- "trademark",
- "manufacturer",
- "designer",
- "description",
- "urlVendor",
- "urlDesigner",
- "licence",
- "licenceURL",
- "---",
- "typoFamilyName",
- "typoSubfamilyName",
- "compatibleFull",
- "sampleText",
- "postScriptCID",
- "wwsFamilyName",
- "wwsSubfamilyName",
- "lightPalette",
- "darkPalette"
- ];
-
- var offset0 = offset;
- var rU = bin.readUshort;
-
- for(var i=0; i<count; i++)
- {
- var platformID = rU(data, offset); offset += 2;
- var encodingID = rU(data, offset); offset += 2;
- var languageID = rU(data, offset); offset += 2;
- var nameID = rU(data, offset); offset += 2;
- var slen = rU(data, offset); offset += 2;
- var noffset = rU(data, offset); offset += 2;
- //console.log(platformID, encodingID, languageID.toString(16), nameID, length, noffset);
-
-
- var soff = offset0 + count*12 + noffset;
- var str;
- if(false){}
- else if(platformID == 0) str = bin.readUnicode(data, soff, slen/2);
- else if(platformID == 3 && encodingID == 0) str = bin.readUnicode(data, soff, slen/2);
- else if(platformID == 1 && encodingID ==25) str = bin.readUnicode(data, soff, slen/2);
- else if(encodingID == 0) str = bin.readASCII (data, soff, slen);
- else if(encodingID == 1) str = bin.readUnicode(data, soff, slen/2);
- else if(encodingID == 3) str = bin.readUnicode(data, soff, slen/2);
- else if(encodingID == 4) str = bin.readUnicode(data, soff, slen/2);
- else if(encodingID == 5) str = bin.readUnicode(data, soff, slen/2);
- else if(encodingID ==10) str = bin.readUnicode(data, soff, slen/2);
-
- else if(platformID == 1) { str = bin.readASCII(data, soff, slen); console.log("reading unknown MAC encoding "+encodingID+" as ASCII") }
- else {
- console.log("unknown encoding "+encodingID + ", platformID: "+platformID);
- str = bin.readASCII(data, soff, slen);
- }
-
- var tid = "p"+platformID+","+(languageID).toString(16);//Typr._platforms[platformID];
- if(obj[tid]==null) obj[tid] = {};
- obj[tid][names[nameID]] = str;
- obj[tid]["_lang"] = languageID;
- //console.log(tid, obj[tid]);
- }
- /*
- if(format == 1)
- {
- var langTagCount = bin.readUshort(data, offset); offset += 2;
- for(var i=0; i<langTagCount; i++)
- {
- var length = bin.readUshort(data, offset); offset += 2;
- var noffset = bin.readUshort(data, offset); offset += 2;
- }
- }
- */
- var out = Typr["T"].name.selectOne(obj), ff="fontFamily";
- if(out[ff]==null) for(var p in obj) if(obj[p][ff]!=null) out[ff]=obj[p][ff];
- return out;
- },
- selectOne :function(obj) {
- //console.log(obj);
- var psn = "postScriptName";
-
- for(var p in obj) if(obj[p][psn]!=null && obj[p]["_lang"]==0x0409) return obj[p]; // United States
- for(var p in obj) if(obj[p][psn]!=null && obj[p]["_lang"]==0x0000) return obj[p]; // Universal
- for(var p in obj) if(obj[p][psn]!=null && obj[p]["_lang"]==0x0c0c) return obj[p]; // Canada
- for(var p in obj) if(obj[p][psn]!=null) return obj[p];
-
- var out;
- for(var p in obj) { out=obj[p]; break; }
- console.log("returning name table with languageID "+ out._lang);
- if(out[psn]==null && out["ID"]!=null) out[psn]=out["ID"];
- return out;
- }
- }
- Typr["T"].OS2 = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var ver = bin.readUshort(data, offset); offset += 2;
-
- var OS2 = Typr["T"].OS2;
-
- var obj = {};
- if (ver==0) OS2.version0(data, offset, obj);
- else if(ver==1) OS2.version1(data, offset, obj);
- else if(ver==2 || ver==3 || ver==4) OS2.version2(data, offset, obj);
- else if(ver==5) OS2.version5(data, offset, obj);
- else throw "unknown OS/2 table version: "+ver;
-
- return obj;
- },
- version0 : function(data, offset, obj)
- {
- var bin = Typr["B"];
- obj["xAvgCharWidth"] = bin.readShort(data, offset); offset += 2;
- obj["usWeightClass"] = bin.readUshort(data, offset); offset += 2;
- obj["usWidthClass"] = bin.readUshort(data, offset); offset += 2;
- obj["fsType"] = bin.readUshort(data, offset); offset += 2;
- obj["ySubscriptXSize"] = bin.readShort(data, offset); offset += 2;
- obj["ySubscriptYSize"] = bin.readShort(data, offset); offset += 2;
- obj["ySubscriptXOffset"] = bin.readShort(data, offset); offset += 2;
- obj["ySubscriptYOffset"] = bin.readShort(data, offset); offset += 2;
- obj["ySuperscriptXSize"] = bin.readShort(data, offset); offset += 2;
- obj["ySuperscriptYSize"] = bin.readShort(data, offset); offset += 2;
- obj["ySuperscriptXOffset"] = bin.readShort(data, offset); offset += 2;
- obj["ySuperscriptYOffset"] = bin.readShort(data, offset); offset += 2;
- obj["yStrikeoutSize"] = bin.readShort(data, offset); offset += 2;
- obj["yStrikeoutPosition"] = bin.readShort(data, offset); offset += 2;
- obj["sFamilyClass"] = bin.readShort(data, offset); offset += 2;
- obj["panose"] = bin.readBytes(data, offset, 10); offset += 10;
- obj["ulUnicodeRange1"] = bin.readUint(data, offset); offset += 4;
- obj["ulUnicodeRange2"] = bin.readUint(data, offset); offset += 4;
- obj["ulUnicodeRange3"] = bin.readUint(data, offset); offset += 4;
- obj["ulUnicodeRange4"] = bin.readUint(data, offset); offset += 4;
- obj["achVendID"] = bin.readASCII(data, offset, 4); offset += 4;
- obj["fsSelection"] = bin.readUshort(data, offset); offset += 2;
- obj["usFirstCharIndex"] = bin.readUshort(data, offset); offset += 2;
- obj["usLastCharIndex"] = bin.readUshort(data, offset); offset += 2;
- obj["sTypoAscender"] = bin.readShort(data, offset); offset += 2;
- obj["sTypoDescender"] = bin.readShort(data, offset); offset += 2;
- obj["sTypoLineGap"] = bin.readShort(data, offset); offset += 2;
- obj["usWinAscent"] = bin.readUshort(data, offset); offset += 2;
- obj["usWinDescent"] = bin.readUshort(data, offset); offset += 2;
- return offset;
- },
- version1 : function(data, offset, obj)
- {
- var bin = Typr["B"];
- offset = Typr["T"].OS2.version0(data, offset, obj);
-
- obj["ulCodePageRange1"] = bin.readUint(data, offset); offset += 4;
- obj["ulCodePageRange2"] = bin.readUint(data, offset); offset += 4;
- return offset;
- },
- version2 : function(data, offset, obj)
- {
- var bin = Typr["B"], rU=bin.readUshort;
- offset = Typr["T"].OS2.version1(data, offset, obj);
-
- obj["sxHeight"] = bin.readShort(data, offset); offset += 2;
- obj["sCapHeight"] = bin.readShort(data, offset); offset += 2;
- obj["usDefault"] = rU(data, offset); offset += 2;
- obj["usBreak"] = rU(data, offset); offset += 2;
- obj["usMaxContext"] = rU(data, offset); offset += 2;
- return offset;
- },
- version5 : function(data, offset, obj)
- {
- var rU = Typr["B"].readUshort;
- offset = Typr["T"].OS2.version2(data, offset, obj);
- obj["usLowerOpticalPointSize"] = rU(data, offset); offset += 2;
- obj["usUpperOpticalPointSize"] = rU(data, offset); offset += 2;
- return offset;
- }
- }
- Typr["T"].post = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var obj = {};
-
- obj["version"] = bin.readFixed(data, offset); offset+=4;
- obj["italicAngle"] = bin.readFixed(data, offset); offset+=4;
- obj["underlinePosition"] = bin.readShort(data, offset); offset+=2;
- obj["underlineThickness"] = bin.readShort(data, offset); offset+=2;
- return obj;
- }
- };
- Typr["T"].SVG = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var obj = { entries: []};
- var offset0 = offset;
- var tableVersion = bin.readUshort(data, offset); offset += 2;
- var svgDocIndexOffset = bin.readUint(data, offset); offset += 4;
- var reserved = bin.readUint(data, offset); offset += 4;
- offset = svgDocIndexOffset + offset0;
- var numEntries = bin.readUshort(data, offset); offset += 2;
- for(var i=0; i<numEntries; i++)
- {
- var startGlyphID = bin.readUshort(data, offset); offset += 2;
- var endGlyphID = bin.readUshort(data, offset); offset += 2;
- var svgDocOffset = bin.readUint (data, offset); offset += 4;
- var svgDocLength = bin.readUint (data, offset); offset += 4;
- var sbuf = new Uint8Array(data.buffer, offset0 + svgDocOffset + svgDocIndexOffset, svgDocLength);
- if(sbuf[0]==0x1f && sbuf[1]==0x8b && sbuf[2]==0x08) sbuf = pako["inflate"](sbuf);
- var svg = bin.readUTF8(sbuf, 0, sbuf.length);
-
- for(var f=startGlyphID; f<=endGlyphID; f++) {
- obj.entries[f] = svg;
- }
- }
- return obj;
- }
- };
- Typr["T"].sbix = {
- parseTab : function(data, offset, length, obj)
- {
- var numGlyphs = obj["maxp"]["numGlyphs"];
- var ooff = offset;
- var bin = Typr["B"];
-
- //var ver = bin.readUshort(data,offset); offset+=2;
- //var flg = bin.readUshort(data,offset); offset+=2;
-
- var numStrikes = bin.readUint (data,offset+4);
-
- var out = [];
- for(var si=numStrikes-1; si<numStrikes; si++) {
- var off = ooff+bin.readUint(data,offset+8+si*4);
-
- //var ppem = bin.readUshort(data,off); off+=2;
- //var ppi = bin.readUshort(data,off); off+=2;
-
- for(var gi=0; gi<numGlyphs; gi++) {
- var aoff = bin.readUint(data,off+4+gi*4);
- var noff = bin.readUint(data,off+4+gi*4+4); if(aoff==noff) { out[gi]=null; continue; }
- var go = off+aoff;
- //var ooX = bin.readUshort(data,go);
- //var ooY = bin.readUshort(data,go+2);
- var tag = bin.readASCII(data,go+4,4); if(tag!="png ") throw tag;
-
- out[gi] = new Uint8Array(data.buffer, data.byteOffset+go+8, noff-aoff-8);
- }
- }
- return out;
- }
- };
- Typr["T"].colr = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var ooff=offset;
- offset+=2;
- var num = bin.readUshort(data,offset); offset+=2;
-
- var boff = bin.readUint(data,offset); offset+=4;
- var loff = bin.readUint(data,offset); offset+=4;
-
- var lnum = bin.readUshort(data,offset); offset+=2;
- //console.log(num,boff,loff,lnum);
-
- var base = {};
- var coff = ooff+boff;
- for(var i=0; i<num; i++) {
- base["g"+bin.readUshort(data,coff)] = [ bin.readUshort(data,coff+2),bin.readUshort(data,coff+4)];
- coff+=6;
- }
- var lays = [];
- coff = ooff+loff;
- for(var i=0; i<lnum; i++) {
- lays.push(bin.readUshort(data,coff), bin.readUshort(data,coff+2)); coff+=4;
- }
- return [base,lays];
- }
- };
- Typr["T"].cpal = {
- parseTab : function(data, offset, length)
- {
- var bin = Typr["B"];
- var ooff=offset;
- var vsn = bin.readUshort(data,offset); offset+=2;
-
- if(vsn==0) {
- var ets = bin.readUshort(data,offset); offset+=2;
- var pts = bin.readUshort(data,offset); offset+=2;
- var tot = bin.readUshort(data,offset); offset+=2;
-
- var fst = bin.readUint(data,offset); offset+=4;
-
- return new Uint8Array(data.buffer,ooff+fst,tot*4);
- /*
- var coff=ooff+fst;
-
- for(var i=0; i<tot; i++) {
- console.log(data[coff],data[coff+1],data[coff+2],data[coff+3]);
- coff+=4;
- }
-
- console.log(ets,pts,tot); */
- }
- else throw vsn;//console.log("unknown color palette",vsn);
- }
- };
|