// // nftr.js //-------------------- // Reads NFTR fonts and compiles them to a texture and character lookup table. Texture is replaceable. // by RHY3756547 // // includes: gl-matrix.js (glMatrix 2.0) // /formats/nitro.js // window.nftr = function(input) { var mainOff; var t = this; this.info = {}; if (input != null) { load(input); } this.load = load; this.drawToCanvas = drawToCanvas; this.measureText = measureText; this.measureMapped = measureMapped; this.mapText = mapText; function load(input) { var view = new DataView(input); var header = null; var offset = 0; var tex; //nitro 3d header header = nitro.readHeader(view); //debugger; if (header.stamp != "RTFN") throw "NFTR invalid. Expected RTFN, found "+header.stamp; offset = 0x10; //nitro header for nftr doesn't have section offsets - they are in order //end nitro var info = t.info; info.type = readChar(view, offset+0x0)+readChar(view, offset+0x1)+readChar(view, offset+0x2)+readChar(view, offset+0x3); info.blockSize = view.getUint32(offset+0x4, true); info.unknown1 = view.getUint8(offset+0x8); info.height = view.getUint8(offset+0x9); info.nullCharIndex = view.getUint16(offset+0xA, true); info.unknown2 = view.getUint8(offset+0xC); info.width = view.getUint8(offset+0xD); info.widthBis = view.getUint8(offset+0xE); info.encoding = view.getUint8(offset+0xF); info.offsetCGLP = view.getUint32(offset+0x10, true); //character graphics info.offsetCWDH = view.getUint32(offset+0x14, true); //character width info.offsetCMAP = view.getUint32(offset+0x18, true); //character map if (info.blockSize == 0x20) { //extra info info.fontHeight = view.getUint8(offset+0x1C); info.fontWidth = view.getUint8(offset+0x1D); info.bearingX = view.getUint8(offset+0x1E); info.bearingY = view.getUint8(offset+0x1F); } loadCGLP(view); loadCWDH(view); loadCMAP(view); mainOff = offset; } function loadCGLP(view) { var offset = t.info.offsetCGLP - 8; var cglp = {}; cglp.type = readChar(view, offset+0x0)+readChar(view, offset+0x1)+readChar(view, offset+0x2)+readChar(view, offset+0x3); cglp.blockSize = view.getUint32(offset+0x4, true); cglp.tileWidth = view.getUint8(offset+0x8); cglp.tileHeight = view.getUint8(offset+0x9); cglp.tileLength = view.getUint16(offset+0xA, true); cglp.unknown = view.getUint16(offset+0xC, true); cglp.depth = view.getUint8(offset+0xE); cglp.rotateMode = view.getUint8(offset+0xF); offset += 0x10; cglp.tiles = []; var total = (cglp.blockSize - 0x10) / cglp.tileLength; for (var i=0; i 0 && offset < view.byteLength) { var cmap = {}; cmap.type = readChar(view, offset+0x0)+readChar(view, offset+0x1)+readChar(view, offset+0x2)+readChar(view, offset+0x3); cmap.blockSize = view.getUint32(offset+0x4, true); cmap.firstChar = view.getUint16(offset+0x8, true); cmap.lastChar = view.getUint16(offset+0xA, true); cmap.typeSection = view.getUint32(offset+0xC, true); cmap.nextOffset = view.getUint32(offset+0x10, true); offset += 0x14; switch (cmap.typeSection & 0xFFFF) { case 1: //char code list (first to last) cmap.charCodes = []; var total = (cmap.lastChar - cmap.firstChar) + 1; var charCode = cmap.firstChar; for (var i=0; i> (bit)) & mask; } else { pind = (curByte >> (bit)) & mask; } var col = pal[pind]; d[ind++] = col[0]; d[ind++] = col[1]; d[ind++] = col[2]; d[ind++] = col[3]; } return data; } }