diff --git a/fonts.js b/fonts.js index 31a5e1fac..2cb8260b2 100644 --- a/fonts.js +++ b/fonts.js @@ -447,6 +447,29 @@ var Font = (function () { return array; }; + function int16(bytes) { + return (bytes[0] << 8) + (bytes[1] & 0xff); + }; + + function int32(bytes) { + return (bytes[0] << 24) + (bytes[1] << 16) + + (bytes[2] << 8) + (bytes[3] & 0xff); + }; + + function getMaxPower2(number) { + var maxPower = 0; + var value = number; + while (value >= 2) { + value /= 2; + maxPower++; + } + + value = 2; + for (var i = 1; i < maxPower; i++) + value *= 2; + return value; + }; + function string16(value) { return String.fromCharCode((value >> 8) & 0xff) + String.fromCharCode(value & 0xff); @@ -467,7 +490,7 @@ var Font = (function () { header += string16(numTables); // searchRange (2 bytes) - var tablesMaxPower2 = FontsUtils.getMaxPower2(numTables); + var tablesMaxPower2 = getMaxPower2(numTables); var searchRange = tablesMaxPower2 * 16; header += string16(searchRange); @@ -488,7 +511,7 @@ var Font = (function () { // length var length = data.length; - + // Per spec tables must be 4-bytes align so add padding as needed while (data.length & 3) data.push(0x00); @@ -499,7 +522,7 @@ var Font = (function () { // checksum var checksum = 0; for (var i = 0; i < length; i+=4) - checksum += FontsUtils.bytesToInteger([data[i], data[i+1], data[i+2], data[i+3]]); + checksum += int16([data[i], data[i+1], data[i+2], data[i+3]]); var tableEntry = tag + string32(checksum) + string32(offset) + string32(length); tableEntry = stringToArray(tableEntry); @@ -546,7 +569,7 @@ var Font = (function () { var headerSize = (12 * 2 + (ranges.length * 5 * 2)); var segCount = ranges.length + 1; var segCount2 = segCount * 2; - var searchRange = FontsUtils.getMaxPower2(segCount) * 2; + var searchRange = getMaxPower2(segCount) * 2; var searchEntry = Math.log(segCount) / Math.log(2); var rangeShift = 2 * segCount - searchRange; @@ -693,9 +716,9 @@ var Font = (function () { String.fromCharCode(tag[2]) + String.fromCharCode(tag[3]); - var checksum = FontsUtils.bytesToInteger(file.getBytes(4)); - var offset = FontsUtils.bytesToInteger(file.getBytes(4)); - var length = FontsUtils.bytesToInteger(file.getBytes(4)); + var checksum = int32(file.getBytes(4)); + var offset = int32(file.getBytes(4)); + var length = int32(file.getBytes(4)); // Read the table associated data var previousPosition = file.pos; @@ -716,26 +739,26 @@ var Font = (function () { function readOpenTypeHeader(ttf) { return { version: ttf.getBytes(4), - numTables: FontsUtils.bytesToInteger(ttf.getBytes(2)), - searchRange: FontsUtils.bytesToInteger(ttf.getBytes(2)), - entrySelector: FontsUtils.bytesToInteger(ttf.getBytes(2)), - rangeShift: FontsUtils.bytesToInteger(ttf.getBytes(2)) + numTables: int16(ttf.getBytes(2)), + searchRange: int16(ttf.getBytes(2)), + entrySelector: int16(ttf.getBytes(2)), + rangeShift: int16(ttf.getBytes(2)) } }; function replaceCMapTable(cmap, font, properties) { font.pos = (font.start ? font.start : 0) + cmap.length; - var version = FontsUtils.bytesToInteger(font.getBytes(2)); - var numTables = FontsUtils.bytesToInteger(font.getBytes(2)); + var version = int16(font.getBytes(2)); + var numTables = int16(font.getBytes(2)); for (var i = 0; i < numTables; i++) { - var platformID = FontsUtils.bytesToInteger(font.getBytes(2)); - var encodingID = FontsUtils.bytesToInteger(font.getBytes(2)); - var offset = FontsUtils.bytesToInteger(font.getBytes(4)); - var format = FontsUtils.bytesToInteger(font.getBytes(2)); - var length = FontsUtils.bytesToInteger(font.getBytes(2)); - var language = FontsUtils.bytesToInteger(font.getBytes(2)); + var platformID = int16(font.getBytes(2)); + var encodingID = int16(font.getBytes(2)); + var offset = int32(font.getBytes(4)); + var format = int16(font.getBytes(2)); + var length = int16(font.getBytes(2)); + var language = int16(font.getBytes(2)); if ((format == 0 && numTables == 1) || (format == 6 && numTables == 1 && !properties.encoding.empty)) { @@ -757,13 +780,13 @@ var Font = (function () { // table. (This looks weird, so I can have missed something), this // works on Linux but seems to fails on Mac so let's rewrite the // cmap table to a 3-1-4 style - var firstCode = FontsUtils.bytesToInteger(font.getBytes(2)); - var entryCount = FontsUtils.bytesToInteger(font.getBytes(2)); + var firstCode = int16(font.getBytes(2)); + var entryCount = int16(font.getBytes(2)); var glyphs = []; var min = 0xffff, max = 0; for (var j = 0; j < entryCount; j++) { - var charcode = FontsUtils.bytesToInteger(font.getBytes(2)); + var charcode = int16(font.getBytes(2)); glyphs.push(charcode); if (charcode < min) @@ -1125,54 +1148,6 @@ var Font = (function () { return constructor; })(); - -/** - * FontsUtils is a static class dedicated to hold codes that are not related - * to fonts in particular and needs to be share between them. - */ -var FontsUtils = { - _bytesArray: new Uint8Array(4), - integerToBytes: function fu_integerToBytes(value, bytesCount) { - var bytes = this._bytesArray; - - if (bytesCount == 1) { - bytes.set([value]); - return bytes[0]; - } else if (bytesCount == 2) { - bytes.set([value >> 8, value & 0xff]); - return [bytes[0], bytes[1]]; - } else if (bytesCount == 4) { - bytes.set([value >> 24, value >> 16, value >> 8, value]); - return [bytes[0], bytes[1], bytes[2], bytes[3]]; - } - - error("This number of bytes " + bytesCount + " is not supported"); - return null; - }, - - bytesToInteger: function fu_bytesToInteger(bytesArray) { - var value = 0; - for (var i = 0; i < bytesArray.length; i++) - value = (value << 8) + bytesArray[i]; - return value; - }, - - getMaxPower2: function fu_getMaxPower2(number) { - var maxPower = 0; - var value = number; - while (value >= 2) { - value /= 2; - maxPower++; - } - - value = 2; - for (var i = 1; i < maxPower; i++) - value *= 2; - return value; - } -}; - - /** * Type1Parser encapsulate the needed code for parsing a Type1 font * program. @@ -1619,10 +1594,7 @@ CFF.prototype = { if (count == 0) return "\x00\x00\x00"; - var data = ""; - var bytes = FontsUtils.integerToBytes(count, 2); - for (var i = 0; i < bytes.length; i++) - data += String.fromCharCode(bytes[i]); + var data = String.fromCharCode(count >> 8, count & 0xff); // Next byte contains the offset size use to reference object in the file // Actually we're using 0x04 to be sure to be able to store everything @@ -1632,9 +1604,8 @@ CFF.prototype = { // Add another offset after this one because we need a new offset var relativeOffset = 1; for (var i = 0; i < count + 1; i++) { - var bytes = FontsUtils.integerToBytes(relativeOffset, 4); - for (var j = 0; j < bytes.length; j++) - data += String.fromCharCode(bytes[j]); + data += String.fromCharCode(relativeOffset >> 24, relativeOffset >> 16, + relativeOffset >> 8, relativeOffset & 0xff); if (objects[i]) relativeOffset += objects[i].length; @@ -1829,8 +1800,7 @@ CFF.prototype = { if (index == -1) index = 0; - var bytes = FontsUtils.integerToBytes(index, 2); - charset += String.fromCharCode(bytes[0]) + String.fromCharCode(bytes[1]); + charset += String.fromCharCode(index >> 8, index & 0xff); } return charset; })(this),