From dad8e9deaf028e17f5f62428306c2a0c41b2cd88 Mon Sep 17 00:00:00 2001 From: Photopea Date: Tue, 6 Sep 2022 22:50:47 +0200 Subject: [PATCH] Add files via upload --- src/Typr.U.js | 466 +++++++++++++++++++++++++++++++++++--------------- src/Typr.js | 183 +++++++++++++++++++- 2 files changed, 506 insertions(+), 143 deletions(-) diff --git a/src/Typr.U.js b/src/Typr.U.js index 6bf68d0..6adaa09 100644 --- a/src/Typr.U.js +++ b/src/Typr.U.js @@ -58,107 +58,165 @@ Typr["U"] = { return {"cmds":tpath.cmds, "crds":tpath.crds}; }, - "codeToGlyph" : function(font, code) - { - var cmap = font["cmap"]; - //console.log(cmap); - // "p3e10" for NotoEmoji-Regular.ttf - var tind = -1, pps=["p3e10","p0e4","p3e1","p1e0","p0e3","p0e1"/*,"p3e3"*/]; - for(var i=0; i>>1); if(arr[mid*k]<=v) l=mid; else r=mid; } + + //var mi = 0; for(var i=0; i=tab.map.length) gid = 0; - else gid = tab.map[code]; - } - /*else if(fmt==2) { - var data=font["_data"], off = cmap.off+tab.off+6, bin=Typr["B"]; - var shKey = bin.readUshort(data,off + 2*(code>>>8)); - var shInd = off + 256*2 + shKey*8; - - var firstCode = bin.readUshort(data,shInd); - var entryCount= bin.readUshort(data,shInd+2); - var idDelta = bin.readShort (data,shInd+4); - var idRangeOffset = bin.readUshort(data,shInd+6); + var wha = [0x9,0xa,0xb,0xc,0xd,0x20,0x85,0xa0,0x1680,0x180e,0x2028,0x2029,0x202f,0x2060,0x3000,0xfeff], whm={}; + for(var i=0; i256) console.log(code,(code>>>8),shKey,firstCode,entryCount,idDelta,idRangeOffset); - //throw "e"; - //console.log(tab, bin.readUshort(data,off)); - //throw "e"; - }*/ - else if(fmt==4) { - var sind = -1, ec = tab.endCount; - if(code>ec[ec.length-1]) sind=-1; - else { - // smallest index with code <= value - sind = arrSearch(ec,1,code); - if(ec[sind]=tab.map.length) gid = 0; + else gid = tab.map[code]; } - if(sind==-1) gid = 0; - else if(code>1) - (tab.idRangeOffset.length-sind)]; - else gli = code + tab.idDelta[sind]; - gid = (gli & 0xFFFF); + /*else if(fmt==2) { + var data=font["_data"], off = cmap.off+tab.off+6, bin=Typr["B"]; + var shKey = bin.readUshort(data,off + 2*(code>>>8)); + var shInd = off + 256*2 + shKey*8; + + var firstCode = bin.readUshort(data,shInd); + var entryCount= bin.readUshort(data,shInd+2); + var idDelta = bin.readShort (data,shInd+4); + var idRangeOffset = bin.readUshort(data,shInd+6); + + if(firstCode<=code && code<=firstCode+entryCount) { + // not completely correct + gid = bin.readUshort(data, shInd+6+idRangeOffset + (code&255)*2); + } + else gid=0; + //if(code>256) console.log(code,(code>>>8),shKey,firstCode,entryCount,idDelta,idRangeOffset); + + //throw "e"; + //console.log(tab, bin.readUshort(data,off)); + //throw "e"; + }*/ + else if(fmt==4) { + var ec = tab.endCount; gid=0; + if(code<=ec[ec.length-1]) { + // smallest index with code <= value + var sind = arrSearch(ec,1,code); + if(ec[sind]=tab.startCount[sind]) { + var gli = 0; + if(tab.idRangeOffset[sind]!=0) gli = tab.glyphIdArray[(code-tab.startCount[sind]) + (tab.idRangeOffset[sind]>>1) - (tab.idRangeOffset.length-sind)]; + else gli = code + tab.idDelta[sind]; + gid = (gli & 0xFFFF); + } + } } - } - else if(fmt==6) { - var off = code-tab.firstCode, arr=tab.glyphIdArray; - if(off<0 || off>=arr.length) gid=0; - else gid = arr[off]; - } - else if(fmt==12) { - var grp = tab.groups; //console.log(grp); throw "e"; - - if(code>grp[grp.length-2]) gid = 0; - else { - var i = arrSearch(grp,3,code); - if(grp[i]<=code && code<=grp[i+1]) { gid = grp[i+2] + (code-grp[i]); } - if(gid==-1) gid=0; + else if(fmt==6) { + var off = code-tab.firstCode, arr=tab.glyphIdArray; + if(off<0 || off>=arr.length) gid=0; + else gid = arr[off]; } - } - else throw "unknown cmap table format "+tab.format; - - //* - var SVG = font["SVG "], loca = font["loca"]; - // if the font claims to have a Glyph for a character, but the glyph is empty, and the character is not "white", it is a lie! - if(gid!=0 && font["CFF "]==null && (SVG==null || SVG.entries[gid]==null) && loca[gid]==loca[gid+1] // loca not present in CFF or SVG fonts - && [0x9,0xa,0xb,0xc,0xd,0x20,0x85,0xa0,0x1680,0x2028,0x2029,0x202f,0x3000, - 0x180e,0x200b,0x200c,0x200d,0x2060,0xfeff].indexOf(code)==-1 && !(0x2000<=code && code<=0x200a)) gid=0; - //*/ - - return gid; - }, + else if(fmt==12) { + var grp = tab.groups; gid=0; //console.log(grp); throw "e"; + + if(code<=grp[grp.length-2]) { + var i = arrSearch(grp,3,code); + if(grp[i]<=code && code<=grp[i+1]) { gid = grp[i+2] + (code-grp[i]); } + } + } + else throw "unknown cmap table format "+tab.format; + + //* + var SVG = font["SVG "], loca = font["loca"]; + // if the font claims to have a Glyph for a character, but the glyph is empty, and the character is not "white", it is a lie! + if(gid!=0 && font["CFF "]==null && (SVG==null || SVG.entries[gid]==null) && loca && loca[gid]==loca[gid+1] // loca not present in CFF or SVG fonts + && whm[code]==null ) gid=0; + //*/ + + return gid; + } + return ctg; + }(), - "glyphToPath" : function(font, gid) + "glyphToPath" : function(font, gid, noColor) { var path = { cmds:[], crds:[] }; - var SVG = font["SVG "], CFF = font["CFF "]; + + + var SVG = font["SVG "], CFF = font["CFF "], COLR=font["COLR"], CBLC=font["CBLC"], CBDT=font["CBDT"], sbix=font["sbix"], upng=window["UPNG"]; var U = Typr["U"]; - if(SVG && SVG.entries[gid]) { + + var strike = null; + if(CBLC && upng) for(var i=0; i1) { + + function toHex(n){ var o=n.toString(16); return (o.length==1 ? "0":"")+o; } + + var CPAL = font["CPAL"], gl = COLR[0]["g"+gid]; + for(var i=0; i=0) no.push(" "); + no.push(it); lstF=isF; + } + return no.join(""); + } + + var out = [], co = 0, lmap = {"M":2,"L":2,"Q":4,"C":6}; - for(var i=0; i 0 && !haveWidth) { + if (stack.length > 0 && stack.length!=4 && !haveWidth) { width = stack.shift() + font["nominalWidthX"]; haveWidth = true; } @@ -792,19 +974,19 @@ Typr["U"] = { } function _tokens(d) { - var ts = [], off = 0, rn=false, cn="", pc=""; // reading number, current number, prev char + var ts = [], off = 0, rn=false, cn="", pc="", lc="", nc=0; // reading number, current number, prev char, lastCommand, number count (after last command while(off>>2; for(var i=0; i>>16)+4); //console.log("growing",nlen); + } + heapu8 = new Uint8Array (mem.buffer); + u32 = new Uint32Array(mem.buffer); + i32 = new Int32Array (mem.buffer); + if(__lastFnt!=fn) { if(blob!=null) { exp["hb_blob_destroy"](blob); @@ -1005,6 +1195,8 @@ Typr["U"] = { font = exp["hb_font_create"](face) __lastFnt = fn; } + if(window["TextEncoder"]==null) { alert("Your browser is too old. Please, update it."); return; } + if(te==null) te = new window["TextEncoder"]("utf8"); var buffer = exp["hb_buffer_create"](); var bytes = te["encode"](str); diff --git a/src/Typr.js b/src/Typr.js index 6bc6829..0ef8746 100644 --- a/src/Typr.js +++ b/src/Typr.js @@ -27,8 +27,13 @@ Typr["parse"] = function(buff) "GPOS", "GSUB", "GDEF",*/ + "CBLC":T.CBLC, + "CBDT":T.CBDT, - "SVG ":T.SVG + "SVG ":T.SVG, + "COLR":T.colr, + "CPAL":T.cpal, + "sbix":T.sbix //"VORG", }; var obj = {"_data":data, "_index":idx, "_offset":offset}; @@ -73,7 +78,7 @@ Typr["findTable"] = function(data, tab, foff) var offset = foff+12; for(var i=0; i=buff.length) throw "error"; - var a = Typr["B"].t.uint8; - a[1] = buff[p]; a[0] = buff[p+1]; + var a = Typr["B"].t.uint16; + a[0] = (buff[p]<<8) | buff[p+1]; return Typr["B"].t.int16[0]; }, readUshort : function(buff, p) @@ -727,7 +732,7 @@ Typr["T"].cmap = { obj.tables.push(subt); } - if(obj.ids[id]!=null) throw "multiple tables for one platform+encoding"; + if(obj.ids[id]!=null) console.log("multiple tables for one platform+encoding: "+id); obj.ids[id] = tind; } return obj; @@ -801,6 +806,71 @@ Typr["T"].cmap = { } }; +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