From b5782854711821209cd87f5cbb8683d05615e5d1 Mon Sep 17 00:00:00 2001 From: mkwiser Date: Fri, 3 Oct 2014 14:44:24 +0800 Subject: [PATCH] add ttfwriter --- demo/js/iconfont.json | 1 + demo/js/ttfparse.js | 2 +- demo/js/ttfwriter.js | 5 +- font/icomoon.ttf | Bin 0 -> 1308 bytes font/icomoon.woff | Bin 0 -> 1384 bytes font/iconfont.eot | Bin 0 -> 5688 bytes font/iconfont.ttf | Bin 31236 -> 5404 bytes font/iconfont.woff | Bin 0 -> 3844 bytes src/ttf/table/cmap.js | 20 ++--- src/ttf/table/cmapwriter.js | 32 ++++--- src/ttf/table/directory.js | 2 +- src/ttf/table/glyfcontour.js | 6 +- src/ttf/table/glyfwriter.js | 89 ++++++++++--------- src/ttf/table/loca.js | 12 ++- src/ttf/table/maxp.js | 37 ++++++-- src/ttf/table/name.js | 42 ++++++--- src/ttf/table/post.js | 39 ++++++--- src/ttf/ttfwriter.js | 14 +-- src/ttf/util/checkSum.js | 36 +++++++- src/ttf/util/readWindowsAllCodes.js | 127 ++++++++++++++++++---------- 20 files changed, 315 insertions(+), 149 deletions(-) create mode 100644 demo/js/iconfont.json create mode 100644 font/icomoon.ttf create mode 100644 font/icomoon.woff create mode 100644 font/iconfont.eot create mode 100644 font/iconfont.woff diff --git a/demo/js/iconfont.json b/demo/js/iconfont.json new file mode 100644 index 0000000..4e8cb64 --- /dev/null +++ b/demo/js/iconfont.json @@ -0,0 +1 @@ +{"version":1,"numTables":15,"searchRenge":128,"entrySelector":3,"rengeShift":112,"tables":{"FFTM":{"name":"FFTM","checkSum":1826967136,"offset":252,"length":28},"OS/2":{"name":"OS/2","checkSum":1462805046,"offset":280,"length":96},"cmap":{"name":"cmap","checkSum":877345668,"offset":376,"length":338},"cvt ":{"name":"cvt ","checkSum":213778120,"offset":2760,"length":36},"fpgm":{"name":"fpgm","checkSum":821534357,"offset":2796,"length":2454},"gasp":{"name":"gasp","checkSum":16,"offset":2752,"length":8},"glyf":{"name":"glyf","checkSum":3220684404,"offset":716,"length":1238},"head":{"name":"head","checkSum":63303459,"offset":1956,"length":54},"hhea":{"name":"hhea","checkSum":126419824,"offset":2012,"length":36},"hmtx":{"name":"hmtx","checkSum":184615113,"offset":2048,"length":24},"loca":{"name":"loca","checkSum":60949657,"offset":2072,"length":16},"maxp":{"name":"maxp","checkSum":19466795,"offset":2088,"length":32},"name":{"name":"name","checkSum":8902151,"offset":2120,"length":558},"post":{"name":"post","checkSum":2967987990,"offset":2680,"length":72},"prep":{"name":"prep","checkSum":2780413542,"offset":5252,"length":149}},"head":{"version":1,"fontRevision":1,"checkSumAdjustment":3974893314,"magickNumber":1594834165,"flags":11,"unitsPerEm":1024,"created":"2014-12-03T12:25:44.000Z","modified":"2014-12-03T12:25:44.000Z","xMin":0,"yMin":-150,"xMax":1023,"yMax":812,"macStyle":0,"lowestRecPPEM":8,"fontDirectionHint":2,"indexToLocFormat":0,"glyphDataFormat":0},"maxp":{"version":1,"numGlyphs":7,"maxPoints":95,"maxContours":5,"maxCompositePoints":0,"maxCompositeContours":0,"maxZones":2,"maxTwilightPoints":38,"maxStorage":52,"maxFunctionDefs":108,"maxInstructionDefs":0,"maxStackElements":138,"maxSizeOfInstructions":2454,"maxComponentElements":0,"maxComponentDepth":0},"loca":[0,80,80,80,712,956,1068],"glyf":[{"contours":[[{"x":34,"y":0,"onCurve":true},{"x":34,"y":682,"onCurve":true},{"x":306,"y":682,"onCurve":true},{"x":306,"y":0,"onCurve":true}],[{"x":68,"y":34,"onCurve":true},{"x":272,"y":34,"onCurve":true},{"x":272,"y":648,"onCurve":true},{"x":68,"y":648,"onCurve":true}]],"xMin":34,"yMin":0,"xMax":306,"yMax":682,"instructions":[64,38,0,0,0,3,2,0,3,87,0,2,1,1,2,75,0,2,2,1,79,4,1,1,2,1,67,0,0,7,6,5,4,0,3,0,3,17,5,15,43],"unicode":[65535],"advanceWidth":374,"leftSideBearing":34,"name":".notdef"},{"contours":[],"unicode":[0,8,29],"advanceWidth":0,"leftSideBearing":0,"name":".null"},{"contours":[],"unicode":[9,13],"advanceWidth":341,"leftSideBearing":0,"name":"nonmarkingreturn"},{"contours":[[{"x":281,"y":543,"onCurve":true},{"x":254,"y":542},{"x":228,"y":542,"onCurve":true},{"x":145,"y":542,"onCurve":true},{"x":127,"y":542},{"x":90,"y":530},{"x":62,"y":505},{"x":44,"y":466},{"x":44,"y":440,"onCurve":true},{"x":44,"y":364,"onCurve":true},{"x":956,"y":364,"onCurve":true},{"x":956,"y":405,"onCurve":true},{"x":956,"y":421},{"x":955,"y":449},{"x":955,"y":453,"onCurve":true},{"x":955,"y":466},{"x":945,"y":498},{"x":921,"y":525},{"x":882,"y":543},{"x":852,"y":543,"onCurve":true},{"x":719,"y":543,"onCurve":true},{"x":719,"y":446,"onCurve":true},{"x":281,"y":446,"onCurve":true}],[{"x":955,"y":310,"onCurve":true},{"x":955,"y":258,"onCurve":true},{"x":955,"y":235},{"x":956,"y":177},{"x":956,"y":119},{"x":935,"y":82},{"x":904,"y":59},{"x":869,"y":50},{"x":855,"y":50,"onCurve":true},{"x":841,"y":49},{"x":810,"y":50},{"x":796,"y":50,"onCurve":true},{"x":764,"y":50,"onCurve":true},{"x":719,"y":178,"onCurve":true},{"x":280,"y":178,"onCurve":true},{"x":236,"y":50,"onCurve":true},{"x":207,"y":50,"onCurve":true},{"x":173,"y":50,"onCurve":true},{"x":153,"y":50},{"x":128,"y":51,"onCurve":true},{"x":103,"y":51},{"x":71,"y":70},{"x":52,"y":97},{"x":44,"y":129},{"x":44,"y":143,"onCurve":true},{"x":44,"y":310,"onCurve":true}],[{"x":163,"y":247,"onCurve":true},{"x":151,"y":247},{"x":133,"y":230},{"x":133,"y":204},{"x":151,"y":187},{"x":163,"y":187,"onCurve":true},{"x":176,"y":187},{"x":194,"y":204},{"x":194,"y":230},{"x":176,"y":247}],[{"x":316,"y":123,"onCurve":true},{"x":308,"y":97},{"x":302,"y":75,"onCurve":true},{"x":297,"y":56},{"x":286,"y":20},{"x":282,"y":6},{"x":280,"y":-10},{"x":284,"y":-23},{"x":299,"y":-31},{"x":313,"y":-31,"onCurve":true},{"x":350,"y":-31,"onCurve":true},{"x":417,"y":-31,"onCurve":true},{"x":498,"y":-31,"onCurve":true},{"x":578,"y":-31,"onCurve":true},{"x":642,"y":-31,"onCurve":true},{"x":678,"y":-31,"onCurve":true},{"x":701,"y":-31},{"x":723,"y":-7},{"x":714,"y":19,"onCurve":true},{"x":709,"y":32},{"x":700,"y":67},{"x":695,"y":84,"onCurve":true},{"x":690,"y":103},{"x":684,"y":123,"onCurve":true}],[{"x":336,"y":498,"onCurve":true},{"x":336,"y":726,"onCurve":true},{"x":336,"y":737},{"x":341,"y":761},{"x":356,"y":780},{"x":382,"y":792},{"x":403,"y":792,"onCurve":true},{"x":591,"y":792,"onCurve":true},{"x":622,"y":792},{"x":663,"y":763},{"x":663,"y":725,"onCurve":true},{"x":663,"y":498,"onCurve":true}]],"xMin":44,"yMin":-31,"xMax":956,"yMax":792,"instructions":[75,176,19,80,88,64,74,2,1,0,13,14,13,0,14,102,0,3,14,1,14,3,94,0,1,8,8,1,92,16,1,9,8,10,6,9,94,17,1,12,6,4,6,12,94,0,11,4,11,105,15,1,8,0,6,12,8,6,88,0,10,7,5,2,4,11,10,4,89,18,1,14,14,13,81,0,13,13,10,14,66,27,75,176,23,80,88,64,75,2,1,0,13,14,13,0,14,102,0,3,14,1,14,3,94,0,1,8,8,1,92,16,1,9,8,10,8,9,10,102,17,1,12,6,4,6,12,94,0,11,4,11,105,15,1,8,0,6,12,8,6,88,0,10,7,5,2,4,11,10,4,89,18,1,14,14,13,81,0,13,13,10,14,66,27,75,176,24,80,88,64,76,2,1,0,13,14,13,0,14,102,0,3,14,1,14,3,94,0,1,8,8,1,92,16,1,9,8,10,8,9,10,102,17,1,12,6,4,6,12,4,102,0,11,4,11,105,15,1,8,0,6,12,8,6,88,0,10,7,5,2,4,11,10,4,89,18,1,14,14,13,81,0,13,13,10,14,66,27,64,78,2,1,0,13,14,13,0,14,102,0,3,14,1,14,3,1,102,0,1,8,14,1,8,100,16,1,9,8,10,8,9,10,102,17,1,12,6,4,6,12,4,102,0,11,4,11,105,15,1,8,0,6,12,8,6,88,0,10,7,5,2,4,11,10,4,89,18,1,14,14,13,81,0,13,13,10,14,66,89,89,89,64,40,83,83,59,59,50,49,23,23,83,94,83,94,91,88,59,82,59,82,75,67,55,53,49,58,50,58,23,48,23,48,81,17,49,24,17,40,21,64,19,22,43],"unicode":[120],"advanceWidth":1001,"leftSideBearing":44,"name":"x"},{"contours":[[{"x":781,"y":196,"onCurve":true},{"x":799,"y":115},{"x":812,"y":50,"onCurve":true},{"x":818,"y":23},{"x":828,"y":-32},{"x":837,"y":-77},{"x":843,"y":-109},{"x":844,"y":-113,"onCurve":true},{"x":847,"y":-133},{"x":823,"y":-147},{"x":808,"y":-147,"onCurve":true},{"x":803,"y":-147},{"x":783,"y":-140},{"x":778,"y":-138,"onCurve":true},{"x":512,"y":17,"onCurve":true},{"x":440,"y":-25},{"x":380,"y":-59,"onCurve":true},{"x":355,"y":-73},{"x":305,"y":-102},{"x":264,"y":-126},{"x":235,"y":-143},{"x":229,"y":-145,"onCurve":true},{"x":219,"y":-150},{"x":198,"y":-147},{"x":180,"y":-134},{"x":172,"y":-117},{"x":174,"y":-108,"onCurve":true},{"x":175,"y":-104},{"x":184,"y":-72},{"x":194,"y":-28},{"x":207,"y":25},{"x":214,"y":52,"onCurve":true},{"x":229,"y":115},{"x":249,"y":195,"onCurve":true},{"x":189,"y":247},{"x":141,"y":288,"onCurve":true},{"x":120,"y":305},{"x":81,"y":339},{"x":49,"y":366},{"x":28,"y":384},{"x":27,"y":385,"onCurve":true},{"x":15,"y":396},{"x":-2,"y":423},{"x":2,"y":452},{"x":20,"y":468},{"x":32,"y":470,"onCurve":true},{"x":347,"y":499,"onCurve":true},{"x":464,"y":772,"onCurve":true},{"x":470,"y":789},{"x":493,"y":812},{"x":512,"y":812,"onCurve":true},{"x":522,"y":812},{"x":537,"y":803},{"x":548,"y":791},{"x":555,"y":778},{"x":557,"y":774,"onCurve":true},{"x":671,"y":501,"onCurve":true},{"x":986,"y":471,"onCurve":true},{"x":1007,"y":466},{"x":1023,"y":452},{"x":1023,"y":437,"onCurve":true},{"x":1023,"y":422},{"x":1006,"y":401},{"x":992,"y":386,"onCurve":true}]],"xMin":0,"yMin":-149,"xMax":1023,"yMax":812,"instructions":[183,33,14,0,3,0,1,1,64,75,176,26,80,88,64,11,0,0,1,0,105,0,1,1,10,1,66,27,64,9,0,1,0,1,104,0,0,0,95,89,180,51,49,41,2,15,43],"unicode":[13362],"advanceWidth":1024,"leftSideBearing":0,"name":"uni3432"},{"contours":[[{"x":77,"y":288,"onCurve":true},{"x":77,"y":458,"onCurve":true},{"x":356,"y":642,"onCurve":true},{"x":426,"y":508,"onCurve":true},{"x":601,"y":645,"onCurve":true},{"x":673,"y":510,"onCurve":true},{"x":849,"y":642,"onCurve":true},{"x":944,"y":501,"onCurve":true},{"x":941,"y":278,"onCurve":true},{"x":807,"y":433,"onCurve":true},{"x":623,"y":299,"onCurve":true},{"x":554,"y":436,"onCurve":true},{"x":370,"y":307,"onCurve":true},{"x":292,"y":439,"onCurve":true}],[{"x":77,"y":-95,"onCurve":true},{"x":77,"y":74,"onCurve":true},{"x":356,"y":258,"onCurve":true},{"x":426,"y":124,"onCurve":true},{"x":601,"y":261,"onCurve":true},{"x":673,"y":126,"onCurve":true},{"x":849,"y":258,"onCurve":true},{"x":944,"y":118,"onCurve":true},{"x":941,"y":-106,"onCurve":true},{"x":807,"y":50,"onCurve":true},{"x":623,"y":-85,"onCurve":true},{"x":554,"y":52,"onCurve":true},{"x":370,"y":-77,"onCurve":true},{"x":292,"y":56,"onCurve":true}]],"xMin":77,"yMin":-106,"xMax":944,"yMax":645,"instructions":[181,22,18,8,4,2,38,43],"unicode":[13367],"advanceWidth":1024,"leftSideBearing":77,"name":"uni3437"},{"contours":[[{"x":564,"y":339,"onCurve":true},{"x":574,"y":454},{"x":663,"y":642},{"x":731,"y":706,"onCurve":true},{"x":899,"y":706,"onCurve":true},{"x":830,"y":642},{"x":753,"y":454},{"x":744,"y":339,"onCurve":true},{"x":879,"y":339,"onCurve":true},{"x":879,"y":187,"onCurve":true},{"x":748,"y":187,"onCurve":true},{"x":759,"y":82},{"x":838,"y":-91},{"x":902,"y":-150,"onCurve":true},{"x":735,"y":-150,"onCurve":true},{"x":671,"y":-91},{"x":582,"y":82},{"x":567,"y":187,"onCurve":true},{"x":458,"y":187,"onCurve":true},{"x":443,"y":82},{"x":355,"y":-91},{"x":290,"y":-150,"onCurve":true},{"x":123,"y":-150,"onCurve":true},{"x":187,"y":-91},{"x":266,"y":82},{"x":278,"y":187,"onCurve":true},{"x":135,"y":187,"onCurve":true},{"x":135,"y":339,"onCurve":true},{"x":282,"y":339,"onCurve":true},{"x":273,"y":454},{"x":196,"y":642},{"x":127,"y":706,"onCurve":true},{"x":294,"y":706,"onCurve":true},{"x":362,"y":642},{"x":452,"y":454},{"x":461,"y":339,"onCurve":true}]],"xMin":123,"yMin":-150,"xMax":902,"yMax":706,"instructions":[64,53,8,1,0,1,0,104,5,1,3,2,3,105,10,9,7,3,1,2,2,1,75,10,9,7,3,1,1,2,80,6,4,2,2,1,2,68,0,0,0,35,0,35,19,17,19,19,19,19,17,19,19,11,23,43],"unicode":[13368],"advanceWidth":1024,"leftSideBearing":123,"name":"uni3438"}],"cmap":{"0":1,"8":1,"9":2,"13":2,"29":1,"120":3,"13362":4,"13367":5,"13368":6,"65535":0},"name":{"fontFamily":"\u0000i\u0000c\u0000o\u0000n\u0000f\u0000o\u0000n\u0000t","fontSubFamily":"\u0000M\u0000e\u0000d\u0000i\u0000u\u0000m","uniqueSubFamily":"\u0000F\u0000o\u0000n\u0000t\u0000F\u0000o\u0000r\u0000g\u0000e\u0000 \u00002\u0000.\u00000\u0000 \u0000:\u0000 \u0000i\u0000c\u0000o\u0000n\u0000f\u0000o\u0000n\u0000t\u0000 \u0000:\u0000 \u00003\u0000-\u00001\u00000\u0000-\u00002\u00000\u00001\u00004","fullName":"\u0000i\u0000c\u0000o\u0000n\u0000f\u0000o\u0000n\u0000t","version":"\u0000V\u0000e\u0000r\u0000s\u0000i\u0000o\u0000n\u0000 \u00001\u0000.\u00000\u0000 \u0000;\u0000 \u0000t\u0000t\u0000f\u0000a\u0000u\u0000t\u0000o\u0000h\u0000i\u0000n\u0000t\u0000 \u0000(\u0000v\u00000\u0000.\u00009\u00004\u0000)\u0000 \u0000-\u0000l\u0000 \u00008\u0000 \u0000-\u0000r\u0000 \u00005\u00000\u0000 \u0000-\u0000G\u0000 \u00002\u00000\u00000\u0000 \u0000-\u0000x\u0000 \u00001\u00004\u0000 \u0000-\u0000w\u0000 \u0000\"\u0000G\u0000\"\u0000 \u0000-\u0000f\u0000 \u0000-\u0000s","postScriptName":"\u0000i\u0000c\u0000o\u0000n\u0000f\u0000o\u0000n\u0000t"},"gasp":{"version":1,"numRanges":1,"GASPRangeTbl":[{"rangeMaxPPEM":65535,"rangeGaspBehavior":15}]},"hhea":{"version":1,"ascent":812,"descent":-150,"lineGap":92,"advanceWidthMax":1024,"minLeftSideBearing":0,"minRightSideBearing":0,"xMaxExtent":1023,"caretSlopeRise":1,"caretSlopeRun":0,"caretOffset":0,"reserved0":0,"reserved1":0,"reserved2":0,"reserved3":0,"metricDataFormat":0,"numOfLongHorMetrics":5},"hmtx":[{"advanceWidth":374,"leftSideBearing":34},{"advanceWidth":0,"leftSideBearing":0},{"advanceWidth":341,"leftSideBearing":0},{"advanceWidth":1001,"leftSideBearing":44},{"advanceWidth":1024,"leftSideBearing":0},{"advanceWidth":1024,"leftSideBearing":77},{"advanceWidth":1024,"leftSideBearing":123}],"post":{"italicAngle":0,"postoints":65411,"underlinePosition":50,"underlineThickness":0,"isFixedPitch":0,"minMemType42":0,"maxMemType42":0,"minMemType1":0,"maxMemType1":7,"format":2,"glyphNameIndex":[0,1,2,91,258,259,260],"names":["uni3432","uni3437","uni3438"]},"OS/2":{"version":4,"xAvgCharWidth":1018,"usWeightClass":500,"usWidthClass":5,"fsType":0,"ySubscriptXSize":665,"ySubscriptYSize":716,"ySubscriptXOffset":0,"ySubscriptYOffset":143,"ySuperscriptXSize":665,"ySuperscriptYSize":716,"ySuperscriptXOffset":0,"ySuperscriptYOffset":491,"yStrikeoutSize":51,"yStrikeoutPosition":265,"sFamilyClass":0,"bFamilyType":2,"bSerifStyle":0,"bWeight":6,"bProportion":3,"bContrast":0,"bStrokeVariation":0,"bArmStyle":0,"bLetterform":0,"bMidline":0,"bXHeight":0,"ulUnicodeRange1":1,"ulUnicodeRange2":134217728,"ulUnicodeRange3":0,"ulUnicodeRange4":0,"achVendID":"PfEd","fsSelection":192,"usFirstCharIndex":120,"usLastCharIndex":13368,"sTypoAscender":812,"sTypoDescender":-212,"sTypoLineGap":92,"usWinAscent":812,"usWinDescent":150,"ulCodePageRange1":1,"ulCodePageRange2":0,"sxHeight":792,"sCapHeight":0,"usDefaultChar":0,"usBreakChar":32,"usMaxContext":1}} \ No newline at end of file diff --git a/demo/js/ttfparse.js b/demo/js/ttfparse.js index 086c7d4..0952014 100644 --- a/demo/js/ttfparse.js +++ b/demo/js/ttfparse.js @@ -42,7 +42,7 @@ define( upFile.addEventListener('change', onUpFileChange); ajaxBinaryFile({ - url: '../font/baiduHealth.ttf', + url: '../font/iconfont.ttf', onSuccess: function(binaryData) { var ttfReader = new ttfreader(); ttfReader.read(binaryData); diff --git a/demo/js/ttfwriter.js b/demo/js/ttfwriter.js index 6d8e302..184c68c 100644 --- a/demo/js/ttfwriter.js +++ b/demo/js/ttfwriter.js @@ -18,13 +18,14 @@ define( * 初始化 */ init: function () { - $.getJSON('./js/baiduHealth.json', function(ttf) { + $.getJSON('./js/iconfont.json', function(ttf) { var reader = new TTFReader(); var writer = new TTFWriter(); var buffer = writer.write(ttf); - var ttfData = reader.read(buffer); + reader.read(buffer); + var ttfData = reader.resolve(); console.log(ttfData); var base64str = 'data:font/ttf;charset=utf-8;base64,' + ttf2base64(buffer); diff --git a/font/icomoon.ttf b/font/icomoon.ttf new file mode 100644 index 0000000000000000000000000000000000000000..980c8ef6e51d41690d1ae6703d0a7a560c034949 GIT binary patch literal 1308 zcmaJ=J!n%=6#h>BUXn^p+NQCkme+p}`Ww?&kn#q#h!vrw76)l!|DkDujnGa$(ZNM@ z5L_HGxhPH!3W9O4T|{(pa0v><$*o&W{O-HYrXBPq_nz-N_nz;Zci(vs0Clk8#n6@M z!I5C+{%d;Pa;E3AnSATa$7_JJkxwpXHuAI)@)g?P^4iwYTEgllr(d3~EM^wu!;`Oo z_Zas_SLpD5m!IV4$h%jvg-wHiT*bGo<>oVZAtw1f@<=wbnMV}EkS9pU-U+SSN>XU+u%|fjokrdy}$6&xC9D&;q4+cnHfrIxJwI{Q~h17(g$KVSgJo-eQt!a!9^fEb=*MMSr+~LvmO@}%}U9(#bhb0fP=M^h{Am9r+7uGg48gV4sS;?6;By`y`!mdNsKhd z+a+EvM!j@(_Vx`(N=g-5Y^y?rbfuKOdtK%vhR;TlrqxbI>1n|*)o_}M+wITw!4)6XBMZEf8fWdAd{9*k3c zq}#<=Yj0Ga&~0Bk?u4rFzY@HICbVOmef!C&!@!_=Ux$x4OfU6#=~gSM6I|>eo^Y|3 zxZA}(;u#nF(M+c63&6mLi^DjLdDXMN5Iss$W38#N*3?*QYOFOi4ls7ijn$f~)XgEw znZr7+Vi7m7fmMf@{MrXFM0V)R>U=Jn%dH=EVv2#wxP>)jC~zbI7aXwyOrBU|5|tu@ a0__5QH?YO^qLbpXTLv3mf7#0ZWBdU{wYWO~ literal 0 HcmV?d00001 diff --git a/font/icomoon.woff b/font/icomoon.woff new file mode 100644 index 0000000000000000000000000000000000000000..6a9efcfc9d9a98b7d38026a64f66913b9a861741 GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/font/iconfont.ttf b/font/iconfont.ttf index e178ff5b2fecafffc8ff9123de02cf68b1cacc8c..47dade917ad39971504b6271d413f38d20b824d9 100644 GIT binary patch delta 920 zcmY+Ce@IhN6vxlK_u1PIYnG)#BBST8blUVyCt0z;iJ()-q%1*)I^A?S+LDETENO16 zAN0o~F^c|>Vij0|6b5Dz2!&D+r3BHBKSGK@|5QR$uk+sg$9uW=+|T!&^X|Fl-tZ4{ zy(k0(01R*z82D;yk2(gvGS@ReXf?e9XIxL#=K}zA8Gu{q>v4v<+2VHr zfWL_jm3^r2F@{0>d*s|cZy=~A@El_iA!}f$%gH9WtH?@1X04AEFo*$MEPQF9|UbVbcPLi}7 z`z>XYBBQ#uqGD@y*}Gu@f|e>~l1@`B&$qnZTJ;($m499j=@&g4VniTJ2V{4FHWz>%d}$W3zW__k%MH` z-mjbPV3Aq-Y~$)CBF4M3kytc*>EpFXY&87$+Z`1ze!3owjgDa=1V&^Ji_oVaK$WdR zLzG9*mqHk2Zk?8Agi=zkE(mSj!XeQb3==>|-=2;QCw*oyIYg}DHo}X$gdCD7l#&7g zNkCPo5RpVwsYTaTbKCCFM$hS+Y;jwg!D~2vIBsi7y)0=R_IS++Eot%3g>1Gt|Ac$0 zx_Zi;oG1KqiiW$YMa5zz5(e5~IPeqnoT6^NDZul{coj<7m7*&RWAKVR(4O>Xvihgw zx8$5chGCDg+)rB3`74-IR|kxsR;YB+O+L^J+OLN4&;coGB!zsizyPk#OM{+8PAn-i zOV<8-ya**w24*SI|1KXNA%;;nNho22<4+H|MT=OzVXYfhiVx*#JuFN9tRy@0X2`7j E4=^;=tpET3 literal 31236 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 diff --git a/font/iconfont.woff b/font/iconfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..d6ff79e675f697a52b0eb3ea7b88ff02a6ee43fd GIT binary patch literal 3844 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 ZHNyZ3g`jLfYlfU9kYQ 29; + }); + + ttf.support.cmap.format4Segments = getSegments(unicodes2Bytes, 0xFFFF); ttf.support.cmap.format4Size = 24 + ttf.support.cmap.format4Segments.length * 8; // We need subtable 12 only if found unicodes with > 2 bytes. - var hasGLyphsOver2Bytes = unicodes.some(function(glyph) { + var hasGLyphsOver2Bytes = unicodes2Bytes.some(function(glyph) { return glyph.unicode > 0xFFFF; }); if (hasGLyphsOver2Bytes) { ttf.support.cmap.hasGLyphsOver2Bytes = hasGLyphsOver2Bytes; - ttf.support.cmap.format12Segments = getSegments(unicodes); + ttf.support.cmap.format12Segments = getSegments(unicodes2Bytes); ttf.support.cmap.format12Size = 16 + ttf.support.cmap.format12Segments.length * 12 } diff --git a/src/ttf/table/directory.js b/src/ttf/table/directory.js index 0ecb92c..0a2933a 100644 --- a/src/ttf/table/directory.js +++ b/src/ttf/table/directory.js @@ -23,7 +23,7 @@ define( for (var i = offset, l = numTables * 16; i < l; i += 16) { var name = reader.readString(i, 4); - + //console.log(name); tables[name] = { name : name, checkSum : reader.readUint32(i + 4), diff --git a/src/ttf/table/glyfcontour.js b/src/ttf/table/glyfcontour.js index f8890c0..0570858 100644 --- a/src/ttf/table/glyfcontour.js +++ b/src/ttf/table/glyfcontour.js @@ -128,9 +128,9 @@ define( val.contours = contours; // FIXME for test - val.flags = flags; - val.xCoordinates = xCoordinates; - val.yCoordinates = yCoordinates; + //val.flags = flags; + //val.xCoordinates = xCoordinates; + //val.yCoordinates = yCoordinates; } } diff --git a/src/ttf/table/glyfwriter.js b/src/ttf/table/glyfwriter.js index 5a2a90e..9a4b005 100644 --- a/src/ttf/table/glyfwriter.js +++ b/src/ttf/table/glyfwriter.js @@ -20,6 +20,7 @@ define( * @return {number} 大小 */ function sizeof(glyf, glyfSupport) { + if (!glyf.contours.length) { return 0; } @@ -27,7 +28,7 @@ define( //fixed header + instructions + endPtsOfContours var result = 10 + 2 - + (glyf.instructions ? glyf.instructions.length : 0) + //+ (glyf.instructions ? glyf.instructions.length : 0) + glyf.contours.length * 2 + glyfSupport.flags.length; @@ -58,27 +59,29 @@ define( // a, b, c, d, e // xy values or points - if(t.e >= -0xFF && t.e <= 0xFF && t.f >= 0xFF && t.f <= 0xFF) { - size += 2; - } - else { + if(t.e < 0 || t.e > 0x7F || t.f < 0 || t.f > 0x7F) { size += 4; } - - // scale - if (t.a != 1 || t.d != 1) { - size += t.a == t.d ? 2 : 4; + else { + size += 2; } // 01 , 10 if (t.b || t.c) { - size += 4; + size += 8; } + else { + // scale + if (t.a != 1 || t.d != 1) { + size += t.a == t.d ? 2 : 4; + } + } + }); - if (glyf.instructions) { - size += 2 + glyf.instructions.length; - } + // if (glyf.instructions) { + // size += 2 + glyf.instructions.length; + // } return size; } @@ -226,6 +229,8 @@ define( ttf.glyf.forEach(function(glyf, index) { + var writerOffset = writer.offset; + if (!glyf.compound && 0 == glyf.contours.length) { return; } @@ -253,7 +258,7 @@ define( var g = glyf.glyfs[i]; // instructions - flags += glyf.instructions ? componentFlag.WE_HAVE_INSTRUCTIONS : 0; + //flags += glyf.instructions ? componentFlag.WE_HAVE_INSTRUCTIONS : 0; // use my metrics flags += g.useMyMetrics ? componentFlag.USE_MY_METRICS : 0; // overlap compound @@ -269,7 +274,7 @@ define( // xy values or points // int 8 放不下,则用int16放 - if(e < -0xFF || e > 0xFF || f < -0xFF || f > 0xFF) { + if(e < 0 || e > 0x7F || f < 0 || f > 0x7F) { flags += componentFlag.ARG_1_AND_2_ARE_WORDS; } @@ -294,8 +299,8 @@ define( } else { - writer.writeInt8(e); - writer.writeInt8(f); + writer.writeUint8(e); + writer.writeUint8(f); } if (componentFlag.WE_HAVE_A_SCALE & flags) { @@ -313,16 +318,17 @@ define( } } - if (glyf.instructions) { - var instructions = glyf.instructions; - writer.writeUint16(instructions.length); - for (var i = 0, l = instructions.length; i < l; i++) { - writer.writeUint8(instructions[i] & 0xFF); - } - } + // if (glyf.instructions) { + // var instructions = glyf.instructions; + // writer.writeUint16(instructions.length); + // for (var i = 0, l = instructions.length; i < l; i++) { + // writer.writeUint8(instructions[i] & 0xFF); + // } + // } } else { + var endPtsOfContours = -1; glyf.contours.forEach(function(contour) { endPtsOfContours += contour.length; @@ -330,16 +336,16 @@ define( }); // not support instruction - if (glyf.instructions) { - var instructions = glyf.instructions; - writer.writeUint16(instructions.length); - for (var i = 0, l = instructions.length; i < l; i++) { - writer.writeUint8(instructions[i] & 0xFF); - } - } - else { + // if (glyf.instructions) { + // var instructions = glyf.instructions; + // writer.writeUint16(instructions.length); + // for (var i = 0, l = instructions.length; i < l; i++) { + // writer.writeUint8(instructions[i] & 0xFF); + // } + // } + // else { writer.writeUint16(0); - } + //} // 获取暂存中的flags var flags = ttf.support.glyf[index].flags; @@ -370,6 +376,8 @@ define( // 4字节对齐 var glyfSize = ttf.support.glyf[index].glyfSize; + //console.log(glyfSize, writer.offset - writerOffset); + // if (glyfSize % 4) { for (var i = 0, l = 4 - glyfSize % 4; i < l; i++) { writer.writeUint8(0); @@ -386,13 +394,10 @@ define( ttf.glyf.forEach(function(glyf) { var glyfSupport = {}; var glyfSupport = glyf.compound ? glyfSupport : getFlags(glyf, glyfSupport); - var contoursSize = glyf.compound ? sizeofCompound(glyf) : sizeof(glyf, glyfSupport); - var size = contoursSize; + var glyfSize = glyf.compound ? sizeofCompound(glyf) : sizeof(glyf, glyfSupport); + var size = glyfSize; - // 记录实际size, 用于4字节对齐 - var glyfSize = size; - - // glyph size must be divisible by 4. + // 4字节对齐 if (size % 4) { size += 4 - size % 4; } @@ -411,6 +416,12 @@ define( var xMin = 16384, yMin = 16384, xMax = -16384, yMax = -16384; var advanceWidthMax = -1, minLeftSideBearing = 16384, minRightSideBearing = 16384, xMaxExtent = -16384; ttf.glyf.forEach(function(glyf) { + + // 如果没有轮廓 + if (!glyf.compound && 0 == glyf.contours.length) { + return; + } + advanceWidthMax = Math.max(advanceWidthMax, glyf.advanceWidth); minLeftSideBearing = Math.min(minLeftSideBearing, glyf.leftSideBearing); minRightSideBearing = Math.min(minRightSideBearing, glyf.advanceWidth - glyf.xMax); diff --git a/src/ttf/table/loca.js b/src/ttf/table/loca.js index b70af7f..2316392 100644 --- a/src/ttf/table/loca.js +++ b/src/ttf/table/loca.js @@ -54,11 +54,19 @@ define( offset += glyfSupport[i].size * sizeRatio; } + // write extra + if (indexToLocFormat) { + writer.writeUint32(offset); + } + else { + writer.writeUint16(offset); + } + return writer; }, size: function(ttf) { - var numGlyphs = ttf.glyf.length; - return ttf.head.indexToLocFormat ? numGlyphs * 4 : numGlyphs * 2; + var locaCount = ttf.glyf.length + 1; + return ttf.head.indexToLocFormat ? locaCount * 4 : locaCount * 2; } } ); diff --git a/src/ttf/table/maxp.js b/src/ttf/table/maxp.js index d5e2b70..de9b639 100644 --- a/src/ttf/table/maxp.js +++ b/src/ttf/table/maxp.js @@ -36,21 +36,42 @@ define( }, size: function(ttf) { var maxPoints = 0, maxContours = 0, maxCompositePoints = 0, - maxCompositeContours = 0; + maxCompositeContours = 0, maxSizeOfInstructions = 0; ttf.glyf.forEach(function(glyf) { // 复合图元 if (glyf.compound) { - maxCompositePoints++; - maxCompositeContours += glyf.glyfs.length; + + var compositeContours = 0; + var compositePoints = 0; + glyf.glyfs.forEach(function(g) { + var cglyf = ttf.glyf[g.glyphIndex]; + compositeContours += cglyf.contours ? cglyf.contours.length : 0; + + if (cglyf.contours && cglyf.contours.length) { + cglyf.contours.forEach(function(contour) { + compositePoints += contour.length; + }); + } + + }); + + maxCompositePoints = Math.max(maxCompositePoints, compositePoints); + maxCompositeContours = Math.max(maxCompositeContours, compositeContours); + } // 简单图元 else { - maxContours += glyf.contours.length; + maxContours = Math.max(maxContours, glyf.contours.length); + + var points = 0, twilightPoints = 0; glyf.contours.forEach(function(contour) { - maxPoints += contour.length; + points += contour.length; }); - } + maxPoints = Math.max(maxPoints, points); + } + + maxSizeOfInstructions += glyf.instructions ? glyf.instructions.length : 0; }); ttf.support.maxp = { @@ -61,14 +82,14 @@ define( maxCompositePoints: maxCompositePoints, maxCompositeContours: maxCompositeContours, maxZones: 2, - maxTwilightPoints: 0, + maxTwilightPoints: 255, // It is unclear how to calculate maxStorage, maxFunctionDefs and maxInstructionDefs. // These are magic constants now, with values exceeding values from FontForge // see svg2ttf on github maxStorage: 10, maxFunctionDefs: 10, maxStackElements: 255, - maxSizeOfInstructions: 0, + maxSizeOfInstructions: maxSizeOfInstructions, maxComponentElements: 0, maxComponentDepth: 0 }; diff --git a/src/ttf/table/name.js b/src/ttf/table/name.js index 5a4bcfb..6e64b1b 100644 --- a/src/ttf/table/name.js +++ b/src/ttf/table/name.js @@ -8,7 +8,7 @@ define( function(require) { var table = require('./table'); - var nameId = require('../enum/nameId'); + var nameIdTbl = require('../enum/nameId'); var string = require('../util/string'); var name = table.create( @@ -31,7 +31,7 @@ define( nameRecord.platformID = reader.readUint16(); nameRecord.platformSpecificID = reader.readUint16(); nameRecord.languageID = reader.readUint16(); - nameRecord.nameID = reader.readUint16(); + nameRecord.nameId = reader.readUint16(); nameRecord.length = reader.readUint16(); nameRecord.offset = reader.readUint16(); nameRecordTbl.push(nameRecord); @@ -54,8 +54,8 @@ define( var nameRecord = nameRecordTbl[i]; if (nameRecord.platformID == platformID && nameRecord.platformSpecificID == platformSpecificID - && nameId[nameRecord.nameID]) { - names[nameId[nameRecord.nameID]] = decodeURIComponent(nameRecord.name); + && nameIdTbl[nameRecord.nameId]) { + names[nameIdTbl[nameRecord.nameId]] = decodeURIComponent(nameRecord.name); } } @@ -75,7 +75,7 @@ define( writer.writeUint16(nameRecord.platformID); writer.writeUint16(nameRecord.platformSpecificID); writer.writeUint16(nameRecord.languageID); - writer.writeUint16(nameRecord.nameID); + writer.writeUint16(nameRecord.nameId); writer.writeUint16(nameRecord.name.length); writer.writeUint16(offset); // offset offset += nameRecord.name.length; @@ -83,7 +83,7 @@ define( // write name tbl strings nameRecordTbl.forEach(function(nameRecord) { - writer.writeString(nameRecord.name); + writer.writeBytes(nameRecord.name); }); return writer; @@ -98,31 +98,47 @@ define( // 中文编码字符将被转化成url encode var size = 6; Object.keys(names).forEach(function(name) { - var id = nameId.names[name]; - var nameStr = encodeURIComponent(names[name] || '').replace(/%00/g, ''); + var id = nameIdTbl.names[name]; + + var utf8Bytes = string.toUTF8Bytes(names[name]); + var usc2Bytes = string.toUCS2Bytes(names[name]); + if (undefined !== id) { // mac nameRecordTbl.push({ - nameID: id, + nameId: id, platformID: 1, platformSpecificID: 0, languageID: 0, - name: nameStr + name: utf8Bytes }); // windows nameRecordTbl.push({ - nameID: id, + nameId: id, platformID: 3, platformSpecificID: 1, languageID: 0, // - name: nameStr + name: usc2Bytes }); // 子表大小 - size += 12 * 2 + nameStr.length * 2; + size += 12 * 2 + utf8Bytes.length + usc2Bytes.length; } }); + + var namingOrder = ['platformID', 'platformSpecificID', 'languageID', 'nameId']; + nameRecordTbl = nameRecordTbl.sort(function(a, b) { + var l = 0; + namingOrder.some(function(name) { + var o = a[name] - b[name]; + if (o) { + l = o; + return true; + } + }); + return l; + }); // 保存预处理信息 ttf.support.name = nameRecordTbl; diff --git a/src/ttf/table/post.js b/src/ttf/table/post.js index dae4d91..b0f69f4 100644 --- a/src/ttf/table/post.js +++ b/src/ttf/table/post.js @@ -19,7 +19,6 @@ define( var Posthead = table.create( 'posthead', [ - ['format', struct.Fixed], ['italicAngle', struct.Fixed], ['postoints', struct.Uint16], ['underlinePosition', struct.Int16], @@ -38,11 +37,16 @@ define( ], { read: function(reader, ttf) { - // 读取表头 - var tbl = new Posthead(this.offset).read(reader, ttf); + var tbl = null; + var format = reader.readFixed(this.offset); // format2 - if(tbl.format == 2) { + if(format == 2) { + + // 读取表头 + tbl = new Posthead(reader.offset).read(reader, ttf); + tbl.format = format; + var numberOfGlyphs = ttf.maxp.numGlyphs; var glyphNameIndex = []; @@ -57,6 +61,11 @@ define( var pascalStringBytes = reader.readBytes(reader.offset, pascalStringLength); tbl.names = string.readPascalString(pascalStringBytes); } + else { + tbl = { + format: format + }; + } return tbl; }, @@ -99,15 +108,25 @@ define( // 这里需要注意,"" 有可能是"\3" length不为0,但是是空字符串 if (glyf.name && glyf.name.charCodeAt(0) > 31) { + + if (glyf.name == '.notdef') { + nameIndexs.push(0); + } + else if (glyf.name == '.null') { + nameIndexs.push(1); + } + else if (glyf.name == 'nonmarkingreturn') { + nameIndexs.push(2); + } // 这里需要注意 // unicode如果小于258,并且glyph名字与默认的名字相等, // 则不需要放入name tbl - if (glyf.unicode - && glyf.unicode[0] < 258 - && postName[glyf.unicode[0]] == glyf.name + else if (glyf.unicode + && glyf.unicode[0] - 29 < 258 + && postName[glyf.unicode[0] - 29] == glyf.name ) { - nameIndexs.push(glyf.unicode[0]); + nameIndexs.push(glyf.unicode[0] - 29); } else { nameIndexs.push(258 + nameIndex++); @@ -119,8 +138,8 @@ define( } // 如果代码点有名字,则按默认的名字 - else if (glyf.unicode && glyf.unicode[0] < 258) { - nameIndexs.push(glyf.unicode[0]); + else if (glyf.unicode && glyf.unicode[0] - 29 < 258) { + nameIndexs.push(glyf.unicode[0] - 29); } // 否则命名为 .notdef else { diff --git a/src/ttf/ttfwriter.js b/src/ttf/ttfwriter.js index b72e69d..adc7a90 100644 --- a/src/ttf/ttfwriter.js +++ b/src/ttf/ttfwriter.js @@ -88,8 +88,8 @@ define( name: tableName, checkSum: 0, offset: offset, - length: size, - tableSize: tableSize + length: tableSize, + size: size }); ttfSize += size; @@ -112,16 +112,18 @@ define( var tableStart = writer.offset; !new supportTables[table.name]().write(writer, ttf); + + console.log(writer.offset - tableStart - table.length); - if (table.tableSize % 4) { + if (table.length % 4) { // 对齐字节 - for (var i = 0, l = 4 - table.tableSize % 4; i < l; i++) { + for (var i = 0, l = 4 - table.length % 4; i < l; i++) { writer.writeUint8(0); } } // 计算校验和 - table.checkSum = checkSum(writer.getBuffer(), tableStart, table.tableSize); + table.checkSum = checkSum(writer.getBuffer(), tableStart, table.size); }); @@ -137,6 +139,8 @@ define( var ttfCheckSum = (0xB1B0AFBA - checkSum(writer.getBuffer()) + 0x100000000) % 0x100000000; writer.writeUint32(ttfCheckSum, ttfHeadOffset + 8); + delete ttf.support; + return writer.getBuffer(); } diff --git a/src/ttf/util/checkSum.js b/src/ttf/util/checkSum.js index 2f3865e..74ae064 100644 --- a/src/ttf/util/checkSum.js +++ b/src/ttf/util/checkSum.js @@ -45,7 +45,41 @@ define( return sum % 0x100000000; } + function ulong(t) { + /*jshint bitwise:false*/ + t &= 0xffffffff; + if (t < 0) { + t += 0x100000000; + } + return t; + } - return checkSum; + function calc_checksum(buffer, offset, length) { + + var offset = offset || 0; + var length = length || buffer.byteLength; + var view = new DataView(buffer, offset, length); + + var sum = 0; + var nlongs = Math.floor(length / 4); + + for (var i = 0; i < nlongs; ++i) { + var t = view.getUint32(i * 4, false); + sum = ulong(sum + t); + } + + var leftBytes = length - nlongs * 4; //extra 1..3 bytes found, because table is not aligned. Need to include them in checksum too. + if (leftBytes > 0) { + var leftRes = 0; + for (i = 0; i < 4; i++) { + /*jshint bitwise:false*/ + leftRes = (leftRes << 8) + ((i < leftBytes) ? view.getUint8(nlongs * 4 + i, false) : 0); + } + sum = ulong(sum + leftRes); + } + return sum; + } + + return calc_checksum; } ); diff --git a/src/ttf/util/readWindowsAllCodes.js b/src/ttf/util/readWindowsAllCodes.js index 0d11c14..97fb6c1 100644 --- a/src/ttf/util/readWindowsAllCodes.js +++ b/src/ttf/util/readWindowsAllCodes.js @@ -18,55 +18,96 @@ define( * @see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html */ function readWindowsAllCodes(tables) { + + var codes = {}; + + // 读取windows unicode 编码段 - var usc2Arr = tables.filter(function(item) { - return item.platformID == 3 && item.encodingID == 1 && item.format == 4; + var format0 = tables.filter(function(item) { + return item.format == 0; }); - if(usc2Arr.length) { - // 只取第一个format - var format4 = usc2Arr[0]; - var segCount = format4.segCountX2 / 2; - - var codes = {}; - - // graphIdArray 和idRangeOffset的偏移量 - var graphIdArrayIndexOffset = (format4.glyphIdArrayOffset - format4.idRangeOffsetOffset) / 2; - - for (var i = 0; i < segCount; ++i) { - // 读取单个字符 - for( - var start = format4.startCode[i], end = format4.endCode[i]; - start <= end; - ++start - ) { - // range offset = 0 - if(format4.idRangeOffset[i] === 0) { - codes[start] = (start + format4.idDelta[i]) % 0x10000; - } - // rely on to glyphIndexArray - else { - var index = i + format4.idRangeOffset[i] / 2 - + (start - format4.startCode[i]) - - graphIdArrayIndexOffset; - - var graphId = format4.glyphIdArray[index]; - if(graphId !== 0) { - codes[start] = (graphId + format4.idDelta[i]) % 0x10000; - } - else { - codes[start] = 0; - } - - } + if (format0.length) { + format0 = format0[0]; + for (var i = 0, l = format0.glyphIdArray.length; i < l ; i++) { + if (format0.glyphIdArray[i]) { + codes[i] = format0.glyphIdArray[i]; } } - - return codes; - } - else { - return {}; } + + + // 读取windows unicode 编码段 + var format12 = tables.filter(function(item) { + return item.platformID == 3 && item.encodingID == 10 && item.format == 12; + }); + + // 读取format12表 + if (format12.length) { + format12 = format12[0]; + for (var i = 0, l = format12.nGroups; i < l ; i++) { + var group = format12.groups[i]; + var start = group.start, end = group.end, startId = group.startId; + for (;start <= end;) { + codes[start++] = startId++; + } + } + } + // 读取format4表 + else { + + // 读取windows unicode 编码段 + var format4 = tables.filter(function(item) { + return item.platformID == 3 && item.encodingID == 1 && item.format == 4; + }); + + if(format4.length) { + // 只取第一个format + format4 = format4[0]; + var segCount = format4.segCountX2 / 2; + + + + // graphIdArray 和idRangeOffset的偏移量 + var graphIdArrayIndexOffset = (format4.glyphIdArrayOffset - format4.idRangeOffsetOffset) / 2; + + for (var i = 0; i < segCount; ++i) { + // 读取单个字符 + for( + var start = format4.startCode[i], end = format4.endCode[i]; + start <= end; + ++start + ) { + // range offset = 0 + if(format4.idRangeOffset[i] === 0) { + codes[start] = (start + format4.idDelta[i]) % 0x10000; + } + // rely on to glyphIndexArray + else { + var index = i + format4.idRangeOffset[i] / 2 + + (start - format4.startCode[i]) + - graphIdArrayIndexOffset; + + var graphId = format4.glyphIdArray[index]; + if(graphId !== 0) { + codes[start] = (graphId + format4.idDelta[i]) % 0x10000; + } + else { + codes[start] = 0; + } + + } + } + } + + } + + } + + // 去除 0xFFFF + delete codes[65535]; + + return codes; } return readWindowsAllCodes;