From 71d0f0d55c4584e2731a9f0e573c183a87f39ea9 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 8 Sep 2011 13:03:30 +0200 Subject: [PATCH 01/39] Remove a useless check in charsToUnicode --- fonts.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fonts.js b/fonts.js index bfdbb0b4a..5622e84e4 100755 --- a/fonts.js +++ b/fonts.js @@ -444,7 +444,6 @@ var Font = (function Font() { var constructor = function font_constructor(name, file, properties) { this.name = name; this.encoding = properties.encoding; - this.glyphs = properties.glyphs; this.sizes = []; var names = name.split("+"); @@ -1368,10 +1367,6 @@ var Font = (function Font() { unicode = charcode; } - // Check if the glyph has already been converted - if (!IsNum(unicode)) - unicode = encoding[charcode].unicode = this.glyphs[unicode].unicode; - // Handle surrogate pairs if (unicode > 0xFFFF) { str += String.fromCharCode(unicode & 0xFFFF); From 81d7d1a72515450b25b07eaf482a3591820db46f Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 8 Sep 2011 17:57:37 +0200 Subject: [PATCH 02/39] Add widths information for the most common fonts cases --- fonts.js | 28 +++++++++++++++++-------- pdf.js | 64 ++++++++++++++++++++++++++------------------------------ 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/fonts.js b/fonts.js index 5622e84e4..cca1d816c 100755 --- a/fonts.js +++ b/fonts.js @@ -140,11 +140,21 @@ var FontMeasure = (function FontMeasure() { ctx.font = rule; current = font; }, - measureText: function fonts_measureText(text) { + measureText: function fonts_measureText(text, encoding, size) { var width; if (measureCache && (width = measureCache[text])) return width; - width = ctx.measureText(text).width / kScalePrecision; + + try { + width = 0.0; + for (var i = 0; i < text.length; i++) { + var charWidth = encoding[text.charCodeAt(i)].width; + width += parseFloat(charWidth); + } + width = width * size / 1000; + } catch(e) { + width = ctx.measureText(text).width / kScalePrecision; + } if (measureCache) measureCache[text] = width; return width; @@ -468,8 +478,7 @@ var Font = (function Font() { (fontName.indexOf('Italic') != -1); // Use 'name' instead of 'fontName' here because the original - // name ArialNarrow for example will be replaced by Helvetica. - this.narrow = (name.indexOf("Narrow") != -1) + // name ArialBlack for example will be replaced by Helvetica. this.black = (name.indexOf("Black") != -1) this.loadedName = fontName.split('-')[0]; @@ -1018,7 +1027,9 @@ var Font = (function Font() { var index = firstCode; for (var j = start; j <= end; j++) { var code = j - firstCode - 1; - encoding[index++] = { unicode: glyphs[code].unicode }; + var mapping = encoding[index + 1] || {}; + mapping.unicode = glyphs[code].unicode; + encoding[index++] = mapping; } return cmap.data = createCMapTable(glyphs); } @@ -2329,12 +2340,11 @@ var Type2CFF = (function() { } } - if (code == -1) { - var mapping = properties.glyphs[glyph] || {}; + var mapping = properties.glyphs[glyph] || {}; + if (code == -1) index = code = mapping.unicode || index; - } - var width = widths[code] || defaultWidth; + var width = mapping.width || defaultWidth; if (code <= 0x1f || (code >= 127 && code <= 255)) code += kCmapGlyphOffset; diff --git a/pdf.js b/pdf.js index 40ffde688..7fff8ae62 100644 --- a/pdf.js +++ b/pdf.js @@ -4273,22 +4273,23 @@ var PartialEvaluator = (function() { var glyphs = {}; for (var i = firstChar; i <= lastChar; i++) { var glyph = differences[i] || baseEncoding[i]; - if (glyph) { - var index = GlyphsUnicode[glyph] || i; - glyphs[glyph] = map[i] = { - unicode: index, - width: properties.widths[i - firstChar] || properties.defaultWidth - }; + var index = GlyphsUnicode[glyph] || i; + map[i] = { + unicode: index, + width: properties.widths[i] || properties.defaultWidth + }; - // If there is no file, the character mapping can't be modified - // but this is unlikely that there is any standard encoding with - // chars below 0x1f, so that's fine. - if (!properties.file) - continue; + if (glyph) + glyphs[glyph] = map[i]; - if (index <= 0x1f || (index >= 127 && index <= 255)) - map[i].unicode += kCmapGlyphOffset; - } + // If there is no file, the character mapping can't be modified + // but this is unlikely that there is any standard encoding with + // chars below 0x1f, so that's fine. + if (!properties.file) + continue; + + if (index <= 0x1f || (index >= 127 && index <= 255)) + map[i].unicode += kCmapGlyphOffset; } if (type == 'TrueType' && dict.has('ToUnicode') && differences) { @@ -4325,10 +4326,9 @@ var PartialEvaluator = (function() { var endRange = tokens[j + 1]; var code = tokens[j + 2]; while (startRange < endRange) { - map[startRange] = { - unicode: code++, - width: 0 - } + var mapping = map[startRange] || {}; + mapping.unicode = code++; + map[startRange] = mapping; ++startRange; } } @@ -4339,10 +4339,9 @@ var PartialEvaluator = (function() { for (var j = 0; j < tokens.length; j += 2) { var index = tokens[j]; var code = tokens[j + 1]; - map[index] = { - unicode: code, - width: 0 - }; + var mapping = map[index] || {}; + mapping.unicode = code; + map[index] = mapping; } break; @@ -4494,13 +4493,13 @@ var PartialEvaluator = (function() { descent: descriptor.get('Descent'), xHeight: descriptor.get('XHeight'), capHeight: descriptor.get('CapHeight'), - defaultWidth: descriptor.get('MissingWidth') || 0, + defaultWidth: parseFloat(descriptor.get('MissingWidth')) || 0, flags: descriptor.get('Flags'), italicAngle: descriptor.get('ItalicAngle'), differences: [], widths: (function() { var glyphWidths = {}; - for (var i = 0; i <= widths.length; i++) + for (var i = 0; i < widths.length; i++) glyphWidths[firstChar++] = widths[i]; return glyphWidths; })(), @@ -4898,6 +4897,7 @@ var CanvasGraphics = (function() { var scaleFactorX = 1, scaleFactorY = 1; var font = current.font; + var baseText= text; if (font) { if (current.fontSize <= kRasterizerMin) { scaleFactorX = scaleFactorY = kScalePrecision; @@ -4907,26 +4907,22 @@ var CanvasGraphics = (function() { text = font.charsToUnicode(text); } + var encoding = current.font.encoding; + var size = current.fontSize; var charSpacing = current.charSpacing; var wordSpacing = current.wordSpacing; var textHScale = current.textHScale; - // This is a poor simulation for Arial Narrow while font-stretch - // is not implemented (bug 3512) - if (current.font.narrow) { - textHScale += 0.2; - charSpacing -= (0.09 * current.fontSize); - } - if (charSpacing != 0 || wordSpacing != 0 || textHScale != 1) { scaleFactorX *= textHScale; ctx.scale(1 / textHScale, 1); var width = 0; for (var i = 0, ii = text.length; i < ii; ++i) { - var c = text.charAt(i); + var c = baseText.charAt(i); ctx.fillText(c, 0, 0); - var charWidth = FontMeasure.measureText(c) + charSpacing; + var charWidth = FontMeasure.measureText(c, encoding, size); + charWidth += charSpacing; if (c.charCodeAt(0) == 32) charWidth += wordSpacing; ctx.translate(charWidth * scaleFactorX, 0); @@ -4935,7 +4931,7 @@ var CanvasGraphics = (function() { current.x += width; } else { ctx.fillText(text, 0, 0); - current.x += FontMeasure.measureText(text); + current.x += FontMeasure.measureText(baseText, encoding, size); } this.ctx.restore(); From bcd86194146651abc05ae335bbbe25ac19b8062c Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 11 Sep 2011 15:23:35 +0200 Subject: [PATCH 03/39] Prevent the deprecated 'dotsection' command in Type1C to hit the sanitizer --- fonts.js | 37 +++++++++++++++++++++++++++++++++--- utils/cffStandardStrings.js | 2 +- utils/fonts_utils.js | 38 +++++++++++++++++++++++-------------- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/fonts.js b/fonts.js index cc353c03b..e10007c94 100755 --- a/fonts.js +++ b/fonts.js @@ -2251,7 +2251,7 @@ var Type2CFF = (function() { var strings = this.getStrings(stringIndex); - var baseDict = this.parseDict(dictIndex.get(0)); + var baseDict = this.parseDict(dictIndex.get(0).data); var topDict = this.getTopDict(baseDict, strings); var bytes = this.bytes; @@ -2276,6 +2276,33 @@ var Type2CFF = (function() { if (hasSupplement) bytes[topDict.Encoding] = 0; + // The CFF specification state that the 'dotsection' command + // (12, 0) is deprecated and treated as a no-op, but all Type2 + // charstrings processors should support them. Unfortunately + // the font sanitizer don't. As a workaround the sequence (12, 0) + // is replaced by a useless (0, hmoveto). + var count = charStrings.length; + for (var i = 0; i < count; i++) { + var charstring = charStrings.get(i); + + var start = charstring.start; + var data = charstring.data; + var length = data.length; + for (var j = 0; j <= length; j) { + var value = data[j++]; + if (value == 12 && data[j++] == 0) { + bytes[start + j - 2] = 139; + bytes[start + j - 1] = 22; + } else if (value === 28) { + j += 2; + } else if (value >= 247 && value <= 254) { + j++; + } else if (value == 255) { + j += 4; + } + } + } + // charstrings contains info about glyphs (one element per glyph // containing mappings for {unicode, width}) var charstrings = this.getCharStrings(charset, charStrings, @@ -2566,7 +2593,7 @@ var Type2CFF = (function() { } else if (value <= 254) { return -((value - 251) * 256) - dict[pos++] - 108; } else { - error('Incorrect byte'); + error('255 is not a valid DICT command'); } return -1; }; @@ -2644,7 +2671,11 @@ var Type2CFF = (function() { var start = offsets[index]; var end = offsets[index + 1]; - return bytes.subarray(start, end); + return { + start: start, + end: end, + data: bytes.subarray(start, end) + } }, length: count, endPos: end diff --git a/utils/cffStandardStrings.js b/utils/cffStandardStrings.js index 09c408ee7..7919b0f17 100644 --- a/utils/cffStandardStrings.js +++ b/utils/cffStandardStrings.js @@ -560,7 +560,7 @@ var CFFDictDataMap = { '18': { name: 'ExpansionFactor' }, - '9': { + '19': { name: 'initialRandomSeed' }, '20': { diff --git a/utils/fonts_utils.js b/utils/fonts_utils.js index 7665906a1..2c05a64ba 100644 --- a/utils/fonts_utils.js +++ b/utils/fonts_utils.js @@ -20,17 +20,27 @@ function readCharset(aStream, aCharstrings) { var charset = {}; var format = aStream.getByte(); + var count = aCharstrings.length - 1; if (format == 0) { charset['.notdef'] = readCharstringEncoding(aCharstrings[0]); - var count = aCharstrings.length - 1; for (var i = 1; i < count + 1; i++) { var sid = aStream.getByte() << 8 | aStream.getByte(); charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]); //log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]); } } else if (format == 1) { - error('Charset Range are not supported'); + for (var i = 1; i < count + 1; i++) { + var first = aStream.getByte(); + first = (first << 8) | aStream.getByte(); + var numLeft = aStream.getByte(); + for (var j = 0; j <= numLeft; j++) { + var sid = first++; + if (CFFStrings[sid] == 'three') + log(aCharstrings[j]); + charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[j]); + } + } } else { error('Invalid charset format'); } @@ -44,6 +54,9 @@ function readCharset(aStream, aCharstrings) { * chapter 3.1. */ function readCharstringEncoding(aString) { + if (!aString) + return ""; + var charstringTokens = []; var count = aString.length; @@ -71,9 +84,9 @@ function readCharstringEncoding(aString) { } else if (value < 247) { token = parseInt(value) - 139; } else if (value < 251) { - token = ((value - 247) * 256) + aString[i++] + 108; + token = (value - 247) * 256 + aString[i++] + 108; } else if (value < 255) { - token = -((value - 251) * 256) - aString[i++] - 108; + token = -(value - 251) * 256 - aString[i++] - 108; } else {// value == 255 token = aString[i++] << 24 | aString[i++] << 16 | aString[i++] << 8 | aString[i]; @@ -146,9 +159,9 @@ function readFontDictData(aString, aMap) { } else if (value <= 246) { token = parseInt(value) - 139; } else if (value <= 250) { - token = ((value - 247) * 256) + aString[i++] + 108; + token = (value - 247) * 256 + aString[i++] + 108; } else if (value <= 254) { - token = -((value - 251) * 256) - aString[i++] - 108; + token = -(value - 251) * 256 - aString[i++] - 108; } else if (value == 255) { error('255 is not a valid DICT command'); } @@ -199,7 +212,7 @@ function readFontIndexData(aStream, aIsByte) { for (var i = 0; i < count + 1; i++) offsets.push(getNextOffset()); - log('Found ' + count + ' objects at offsets :' + + dump('Found ' + count + ' objects at offsets :' + offsets + ' (offsize: ' + offsize + ')'); // Now extract the objects @@ -285,23 +298,20 @@ var Type2Parser = function(aFilePath) { font.set('hdrSize', aStream.getByte()); font.set('offsize', aStream.getByte()); - // Move the cursor after the header - aStream.skip(font.get('hdrSize') - aStream.pos); - // Read the NAME Index dump('Reading Index: Names'); font.set('Names', readFontIndexData(aStream)); - log('Names: ' + font.get('Names')); + dump('Names: ' + font.get('Names')); // Read the Top Dict Index dump('Reading Index: TopDict'); var topDict = readFontIndexData(aStream, true); - log('TopDict: ' + topDict); + dump('TopDict: ' + topDict); // Read the String Index dump('Reading Index: Strings'); var strings = readFontIndexData(aStream); - log('strings: ' + strings); + dump('strings: ' + strings); // Fill up the Strings dictionary with the new unique strings for (var i = 0; i < strings.length; i++) @@ -321,7 +331,7 @@ var Type2Parser = function(aFilePath) { // Reading Private Dict var priv = font.get('Private'); - log('Reading Private Dict (offset: ' + priv.offset + + dump('Reading Private Dict (offset: ' + priv.offset + ' size: ' + priv.size + ')'); aStream.pos = priv.offset; From a7332d178a53fbc99e5f668f2a71d85a1a4ee82d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 11 Sep 2011 15:32:32 +0200 Subject: [PATCH 04/39] Fix a small error in font encoding --- pdf.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index b4fe814c2..f279e0cdc 100644 --- a/pdf.js +++ b/pdf.js @@ -4939,7 +4939,6 @@ var CanvasGraphics = (function() { } var composite = font.composite; - var encoding = font.encoding; var fontSize = current.fontSize; var charSpacing = current.charSpacing; var wordSpacing = current.wordSpacing; @@ -4956,7 +4955,9 @@ var CanvasGraphics = (function() { var charcode = originalText.charCodeAt(i); } - var charWidth = font.encoding[charcode].width * fontSize * 0.001; + var encoding = font.encoding[charcode]; + var charWidth = (encoding ? encoding.width : font.defaultWidth); + charWidth *= (fontSize * 0.001); charWidth += charSpacing; if (charcode == 32) charWidth += wordSpacing; From ae0f5e62747fd4083c9b76babb790ad11f971707 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 11 Sep 2011 16:14:28 +0200 Subject: [PATCH 05/39] Fix a regression caused by the last patch to resolve the 'dotsection' issue --- fonts.js | 18 +- utils/cffStandardStrings.js | 394 ------------------------------------ 2 files changed, 9 insertions(+), 403 deletions(-) diff --git a/fonts.js b/fonts.js index e10007c94..8323f895d 100755 --- a/fonts.js +++ b/fonts.js @@ -2534,20 +2534,20 @@ var Type2CFF = (function() { } return dict; }, - getStrings: function cff_getstrings(stringIndex) { - function bytesToString(bytesArr) { - var s = ''; - for (var i = 0, ii = bytesArr.length; i < ii; ++i) - s += String.fromCharCode(bytesArr[i]); - return s; + getStrings: function cff_getStrings(stringIndex) { + function bytesToString(bytesArray) { + var str = ''; + for (var i = 0, length = bytesArray.length; i < length; i++) + str += String.fromCharCode(bytesArray[i]); + return str; } var stringArray = []; - for (var i = 0, ii = CFFStrings.length; i < ii; ++i) + for (var i = 0, length = CFFStrings.length; i < length; i++) stringArray.push(CFFStrings[i]); - for (var i = 0, ii = stringIndex.length; i < ii; ++i) - stringArray.push(bytesToString(stringIndex.get(i))); + for (var i = 0, length = stringIndex.length; i < length; i++) + stringArray.push(bytesToString(stringIndex.get(i).data)); return stringArray; }, diff --git a/utils/cffStandardStrings.js b/utils/cffStandardStrings.js index 7919b0f17..4a63ff597 100644 --- a/utils/cffStandardStrings.js +++ b/utils/cffStandardStrings.js @@ -3,400 +3,6 @@ 'use strict'; -var CFFStrings = [ - '.notdef', - 'space', - 'exclam', - 'quotedbl', - 'numbersign', - 'dollar', - 'percent', - 'ampersand', - 'quoteright', - 'parenleft', - 'parenright', - 'asterisk', - 'plus', - 'comma', - 'hyphen', - 'period', - 'slash', - 'zero', - 'one', - 'two', - 'three', - 'four', - 'five', - 'six', - 'seven', - 'eight', - 'nine', - 'colon', - 'semicolon', - 'less', - 'equal', - 'greater', - 'question', - 'at', - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', - 'bracketleft', - 'backslash', - 'bracketright', - 'asciicircum', - 'underscore', - 'quoteleft', - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z', - 'braceleft', - 'bar', - 'braceright', - 'asciitilde', - 'exclamdown', - 'cent', - 'sterling', - 'fraction', - 'yen', - 'florin', - 'section', - 'currency', - 'quotesingle', - 'quotedblleft', - 'guillemotleft', - 'guilsinglleft', - 'guilsinglright', - 'fi', - 'fl', - 'endash', - 'dagger', - 'daggerdbl', - 'periodcentered', - 'paragraph', - 'bullet', - 'quotesinglbase', - 'quotedblbase', - 'quotedblright', - 'guillemotright', - 'ellipsis', - 'perthousand', - 'questiondown', - 'grave', - 'acute', - 'circumflex', - 'tilde', - 'macron', - 'breve', - 'dotaccent', - 'dieresis', - 'ring', - 'cedilla', - 'hungarumlaut', - 'ogonek', - 'caron', - 'emdash', - 'AE', - 'ordfeminine', - 'Lslash', - 'Oslash', - 'OE', - 'ordmasculine', - 'ae', - 'dotlessi', - 'lslash', - 'oslash', - 'oe', - 'germandbls', - 'onesuperior', - 'logicalnot', - 'mu', - 'trademark', - 'Eth', - 'onehalf', - 'plusminus', - 'Thorn', - 'onequarter', - 'divide', - 'brokenbar', - 'degree', - 'thorn', - 'threequarters', - 'twosuperior', - 'registered', - 'minus', - 'eth', - 'multiply', - 'threesuperior', - 'copyright', - 'Aacute', - 'Acircumflex', - 'Adieresis', - 'Agrave', - 'Aring', - 'Atilde', - 'Ccedilla', - 'Eacute', - 'Ecircumflex', - 'Edieresis', - 'Egrave', - 'Iacute', - 'Icircumflex', - 'Idieresis', - 'Igrave', - 'Ntilde', - 'Oacute', - 'Ocircumflex', - 'Odieresis', - 'Ograve', - 'Otilde', - 'Scaron', - 'Uacute', - 'Ucircumflex', - 'Udieresis', - 'Ugrave', - 'Yacute', - 'Ydieresis', - 'Zcaron', - 'aacute', - 'acircumflex', - 'adieresis', - 'agrave', - 'aring', - 'atilde', - 'ccedilla', - 'eacute', - 'ecircumflex', - 'edieresis', - 'egrave', - 'iacute', - 'icircumflex', - 'idieresis', - 'igrave', - 'ntilde', - 'oacute', - 'ocircumflex', - 'odieresis', - 'ograve', - 'otilde', - 'scaron', - 'uacute', - 'ucircumflex', - 'udieresis', - 'ugrave', - 'yacute', - 'ydieresis', - 'zcaron', - 'exclamsmall', - 'Hungarumlautsmall', - 'dollaroldstyle', - 'dollarsuperior', - 'ampersandsmall', - 'Acutesmall', - 'parenleftsuperior', - 'parenrightsuperior', - '266 ff', - 'onedotenleader', - 'zerooldstyle', - 'oneoldstyle', - 'twooldstyle', - 'threeoldstyle', - 'fouroldstyle', - 'fiveoldstyle', - 'sixoldstyle', - 'sevenoldstyle', - 'eightoldstyle', - 'nineoldstyle', - 'commasuperior', - 'threequartersemdash', - 'periodsuperior', - 'questionsmall', - 'asuperior', - 'bsuperior', - 'centsuperior', - 'dsuperior', - 'esuperior', - 'isuperior', - 'lsuperior', - 'msuperior', - 'nsuperior', - 'osuperior', - 'rsuperior', - 'ssuperior', - 'tsuperior', - 'ff', - 'ffi', - 'ffl', - 'parenleftinferior', - 'parenrightinferior', - 'Circumflexsmall', - 'hyphensuperior', - 'Gravesmall', - 'Asmall', - 'Bsmall', - 'Csmall', - 'Dsmall', - 'Esmall', - 'Fsmall', - 'Gsmall', - 'Hsmall', - 'Ismall', - 'Jsmall', - 'Ksmall', - 'Lsmall', - 'Msmall', - 'Nsmall', - 'Osmall', - 'Psmall', - 'Qsmall', - 'Rsmall', - 'Ssmall', - 'Tsmall', - 'Usmall', - 'Vsmall', - 'Wsmall', - 'Xsmall', - 'Ysmall', - 'Zsmall', - 'colonmonetary', - 'onefitted', - 'rupiah', - 'Tildesmall', - 'exclamdownsmall', - 'centoldstyle', - 'Lslashsmall', - 'Scaronsmall', - 'Zcaronsmall', - 'Dieresissmall', - 'Brevesmall', - 'Caronsmall', - 'Dotaccentsmall', - 'Macronsmall', - 'figuredash', - 'hypheninferior', - 'Ogoneksmall', - 'Ringsmall', - 'Cedillasmall', - 'questiondownsmall', - 'oneeighth', - 'threeeighths', - 'fiveeighths', - 'seveneighths', - 'onethird', - 'twothirds', - 'zerosuperior', - 'foursuperior', - 'fivesuperior', - 'sixsuperior', - 'sevensuperior', - 'eightsuperior', - 'ninesuperior', - 'zeroinferior', - 'oneinferior', - 'twoinferior', - 'threeinferior', - 'fourinferior', - 'fiveinferior', - 'sixinferior', - 'seveninferior', - 'eightinferior', - 'nineinferior', - 'centinferior', - 'dollarinferior', - 'periodinferior', - 'commainferior', - 'Agravesmall', - 'Aacutesmall', - 'Acircumflexsmall', - 'Atildesmall', - 'Adieresissmall', - 'Aringsmall', - 'AEsmall', - 'Ccedillasmall', - 'Egravesmall', - 'Eacutesmall', - 'Ecircumflexsmall', - 'Edieresissmall', - 'Igravesmall', - 'Iacutesmall', - 'Icircumflexsmall', - 'Idieresissmall', - 'Ethsmall', - 'Ntildesmall', - 'Ogravesmall', - 'Oacutesmall', - 'Ocircumflexsmall', - 'Otildesmall', - 'Odieresissmall', - 'OEsmall', - 'Oslashsmall', - 'Ugravesmall', - 'Uacutesmall', - 'Ucircumflexsmall', - 'Udieresissmall', - 'Yacutesmall', - 'Thornsmall', - 'Ydieresissmall', - '001.000', - '001.001', - '001.002', - '001.003', - 'Black', - 'Bold', - 'Book', - 'Light', - 'Medium', - 'Regular', - 'Roman', - 'Semibold' -]; - var CFFEncodingMap = { '0': '-reserved-', '1': 'hstem', From 95ca8ede85f2d08f6d67cc93394d436ad75e8076 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Sun, 11 Sep 2011 17:38:02 +0200 Subject: [PATCH 06/39] Add support for Type1C advanced charsets --- charsets.js | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ fonts.js | 35 ++++++++++------- web/viewer.html | 1 + 3 files changed, 122 insertions(+), 15 deletions(-) create mode 100644 charsets.js diff --git a/charsets.js b/charsets.js new file mode 100644 index 000000000..4066976c9 --- /dev/null +++ b/charsets.js @@ -0,0 +1,101 @@ + +var ISOAdobeCharset = [ + ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", + "percent", "ampersand", "quoteright", "parenleft", "parenright", + "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", + "one", "two", "three", "four", "five", "six", "seven", "eight", + "nine", "colon", "semicolon", "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", + "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", + "sterling", "fraction", "yen", "florin", "section", "currency", + "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", + "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", + "periodcentered", "paragraph", "bullet", "quotesinglbase", + "quotedblbase", "quotedblright", "guillemotright", "ellipsis", + "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", + "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", + "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", + "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", + "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", + "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", + "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", + "registered", "minus", "eth", "multiply", "threesuperior", "copyright", + "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", + "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", + "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", + "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", + "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", + "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", + "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", + "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", + "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", + "ugrave", "yacute", "ydieresis", "zcaron" +]; + +var ExpertCharset = [ + ".notdef", "space", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", + "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", + "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", + "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", + "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", + "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", + "colon", "semicolon", "commasuperior", "threequartersemdash", + "periodsuperior", "questionsmall", "asuperior", "bsuperior", + "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", + "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", + "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", + "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", + "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", + "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", + "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", + "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", + "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", + "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", + "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", + "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", + "Cedillasmall", "onequarter", "onehalf", "threequarters", + "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", + "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", + "twosuperior", "threesuperior", "foursuperior", "fivesuperior", + "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", + "zeroinferior", "oneinferior", "twoinferior", "threeinferior", + "fourinferior", "fiveinferior", "sixinferior", "seveninferior", + "eightinferior", "nineinferior", "centinferior", "dollarinferior", + "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", + "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", + "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", + "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", + "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", + "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", + "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", + "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", + "Ydieresissmall" +]; + +var ExpertSubsetCharset = [ + ".notdef", "space", "dollaroldstyle", "dollarsuperior", + "parenleftsuperior", "parenrightsuperior", "twodotenleader", + "onedotenleader", "comma", "hyphen", "period", "fraction", + "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", + "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", + "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", + "threequartersemdash", "periodsuperior", "asuperior", "bsuperior", + "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", + "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", + "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", + "parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted", + "rupiah", "centoldstyle", "figuredash", "hypheninferior", "onequarter", + "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", + "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", + "twosuperior", "threesuperior", "foursuperior", "fivesuperior", + "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", + "zeroinferior", "oneinferior", "twoinferior", "threeinferior", + "fourinferior", "fiveinferior", "sixinferior", "seveninferior", + "eightinferior", "nineinferior", "centinferior", "dollarinferior", + "periodinferior", "commainferior" +]; + diff --git a/fonts.js b/fonts.js index 8323f895d..6a361e60e 100755 --- a/fonts.js +++ b/fonts.js @@ -2429,37 +2429,42 @@ var Type2CFF = (function() { }, parseCharsets: function cff_parsecharsets(pos, length, strings) { + if (pos == 0) { + return ISOAdobeCharset; + } else if (pos == 1) { + return CFFExpertCharset; + } else if (pos == 2) { + return CFFExpertSubsetCharset; + } + var bytes = this.bytes; var format = bytes[pos++]; var charset = ['.notdef']; + // subtract 1 for the .notdef glyph length -= 1; switch (format) { case 0: - for (var i = 0; i < length; ++i) { - var id = bytes[pos++]; - id = (id << 8) | bytes[pos++]; - charset.push(strings[id]); + for (var i = 0; i < length; i++) { + var sid = (bytes[pos++] << 8) | bytes[pos++]; + charset.push(strings[sid]); } break; case 1: while (charset.length <= length) { - var first = bytes[pos++]; - first = (first << 8) | bytes[pos++]; - var numLeft = bytes[pos++]; - for (var i = 0; i <= numLeft; ++i) - charset.push(strings[first++]); + var sid = (bytes[pos++] << 8) | bytes[pos++]; + var count = bytes[pos++]; + for (var i = 0; i <= count; i++) + charset.push(strings[sid++]); } break; case 2: while (charset.length <= length) { - var first = bytes[pos++]; - first = (first << 8) | bytes[pos++]; - var numLeft = bytes[pos++]; - numLeft = (numLeft << 8) | bytes[pos++]; - for (var i = 0; i <= numLeft; ++i) - charset.push(strings[first++]); + var sid = (bytes[pos++] << 8) | bytes[pos++]; + var count = (bytes[pos++] << 8) | bytes[pos++]; + for (var i = 0; i <= count; i++) + charset.push(strings[sid++]); } break; default: diff --git a/web/viewer.html b/web/viewer.html index a53593df3..00950a44c 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -11,6 +11,7 @@ + From 538d26521d02bcc0690555dd2f6c30b1ef59d892 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 12 Sep 2011 18:32:46 +0200 Subject: [PATCH 07/39] Basic support for the embedded font file of CIDFontType0 --- fonts.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/fonts.js b/fonts.js index 6a361e60e..beecf0459 100755 --- a/fonts.js +++ b/fonts.js @@ -448,7 +448,7 @@ var Font = (function Font() { this.mimetype = 'font/opentype'; var subtype = properties.subtype; - var cff = (subtype === 'Type1C') ? + var cff = (subtype == 'Type1C' || properties.type == 'CIDFontType0') ? new Type2CFF(file, properties) : new CFF(name, file, properties); // Wrap the CFF data inside an OTF font file @@ -2256,11 +2256,16 @@ var Type2CFF = (function() { var bytes = this.bytes; + var privateDict = {}; var privateInfo = topDict.Private; - var privOffset = privateInfo[1], privLength = privateInfo[0]; - var privBytes = bytes.subarray(privOffset, privOffset + privLength); - baseDict = this.parseDict(privBytes); - var privDict = this.getPrivDict(baseDict, strings); + if (privateInfo) { + var privOffset = privateInfo[1], privLength = privateInfo[0]; + var privBytes = bytes.subarray(privOffset, privOffset + privLength); + baseDict = this.parseDict(privBytes); + privateDict = this.getPrivDict(baseDict, strings); + } else { + privateDict.defaultWidthX = properties.defaultWidth; + } var charStrings = this.parseIndex(topDict.CharStrings); var charset = this.parseCharsets(topDict.charset, @@ -2306,7 +2311,7 @@ var Type2CFF = (function() { // charstrings contains info about glyphs (one element per glyph // containing mappings for {unicode, width}) var charstrings = this.getCharStrings(charset, charStrings, - privDict, this.properties); + privateDict, this.properties); // create the mapping between charstring and glyph id var glyphIds = []; @@ -2323,10 +2328,8 @@ var Type2CFF = (function() { }, getCharStrings: function cff_charstrings(charsets, charStrings, - privDict, properties) { - var defaultWidth = privDict['defaultWidthX']; - var nominalWidth = privDict['nominalWidthX']; - + privateDict, properties) { + var defaultWidth = privateDict['defaultWidthX']; var charstrings = []; var differences = properties.differences; var index = 0; From f3c20150bd4b04de6d06cae0870f7a2f744aadf3 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 20 Sep 2011 04:26:37 +0200 Subject: [PATCH 08/39] Fix lint errors and add metrics.js and charsets.js to the default set of pdf files in the Makefile --- Makefile | 2 + charsets.js | 182 ++++++++++++++++++++++++++-------------------------- fonts.js | 4 +- 3 files changed, 95 insertions(+), 93 deletions(-) diff --git a/Makefile b/Makefile index fb4ffe9cb..56b597e5f 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,8 @@ PDF_JS_FILES = \ pdf.js \ crypto.js \ fonts.js \ + metrics.js \ + charsets.js \ glyphlist.js \ $(NULL) diff --git a/charsets.js b/charsets.js index 4066976c9..59fcdf5cf 100644 --- a/charsets.js +++ b/charsets.js @@ -1,101 +1,101 @@ var ISOAdobeCharset = [ - ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", - "percent", "ampersand", "quoteright", "parenleft", "parenright", - "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", - "one", "two", "three", "four", "five", "six", "seven", "eight", - "nine", "colon", "semicolon", "less", "equal", "greater", "question", - "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", - "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", - "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", - "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", - "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", - "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", - "sterling", "fraction", "yen", "florin", "section", "currency", - "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", - "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", - "periodcentered", "paragraph", "bullet", "quotesinglbase", - "quotedblbase", "quotedblright", "guillemotright", "ellipsis", - "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", - "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", - "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", - "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", - "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", - "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", - "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", - "registered", "minus", "eth", "multiply", "threesuperior", "copyright", - "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", - "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", - "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", - "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", - "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", - "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", - "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", - "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", - "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", - "ugrave", "yacute", "ydieresis", "zcaron" + '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', + 'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright', + 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', + 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', + 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', + 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', + 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', + 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', + 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', + 'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl', + 'periodcentered', 'paragraph', 'bullet', 'quotesinglbase', + 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', + 'perthousand', 'questiondown', 'grave', 'acute', 'circumflex', 'tilde', + 'macron', 'breve', 'dotaccent', 'dieresis', 'ring', 'cedilla', + 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', + 'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', 'dotlessi', 'lslash', + 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu', + 'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', + 'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', 'twosuperior', + 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright', + 'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', + 'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Iacute', + 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex', + 'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', + 'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', 'aacute', + 'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla', + 'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', + 'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', 'odieresis', + 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', + 'ugrave', 'yacute', 'ydieresis', 'zcaron' ]; var ExpertCharset = [ - ".notdef", "space", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", - "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", - "parenrightsuperior", "twodotenleader", "onedotenleader", "comma", - "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle", - "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", - "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", - "colon", "semicolon", "commasuperior", "threequartersemdash", - "periodsuperior", "questionsmall", "asuperior", "bsuperior", - "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", - "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", - "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", - "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", - "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", - "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", - "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", - "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", - "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", - "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", - "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", - "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", - "Cedillasmall", "onequarter", "onehalf", "threequarters", - "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", - "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", - "twosuperior", "threesuperior", "foursuperior", "fivesuperior", - "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", - "zeroinferior", "oneinferior", "twoinferior", "threeinferior", - "fourinferior", "fiveinferior", "sixinferior", "seveninferior", - "eightinferior", "nineinferior", "centinferior", "dollarinferior", - "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", - "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", - "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", - "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", - "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", - "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", - "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", - "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", - "Ydieresissmall" + '.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', + 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', + 'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma', + 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', + 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', + 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', + 'colon', 'semicolon', 'commasuperior', 'threequartersemdash', + 'periodsuperior', 'questionsmall', 'asuperior', 'bsuperior', + 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', + 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', + 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', + 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', + 'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', + 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', + 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', + 'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', + 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall', 'centoldstyle', + 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', + 'Brevesmall', 'Caronsmall', 'Dotaccentsmall', 'Macronsmall', + 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', + 'Cedillasmall', 'onequarter', 'onehalf', 'threequarters', + 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', + 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', + 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', + 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', + 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', + 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', + 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', + 'periodinferior', 'commainferior', 'Agravesmall', 'Aacutesmall', + 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall', + 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', + 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', + 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', + 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', + 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', + 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', + 'Ydieresissmall' ]; var ExpertSubsetCharset = [ - ".notdef", "space", "dollaroldstyle", "dollarsuperior", - "parenleftsuperior", "parenrightsuperior", "twodotenleader", - "onedotenleader", "comma", "hyphen", "period", "fraction", - "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", - "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", - "eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior", - "threequartersemdash", "periodsuperior", "asuperior", "bsuperior", - "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", - "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", - "tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", - "parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted", - "rupiah", "centoldstyle", "figuredash", "hypheninferior", "onequarter", - "onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths", - "seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior", - "twosuperior", "threesuperior", "foursuperior", "fivesuperior", - "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", - "zeroinferior", "oneinferior", "twoinferior", "threeinferior", - "fourinferior", "fiveinferior", "sixinferior", "seveninferior", - "eightinferior", "nineinferior", "centinferior", "dollarinferior", - "periodinferior", "commainferior" + '.notdef', 'space', 'dollaroldstyle', 'dollarsuperior', + 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', + 'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', + 'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle', + 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', + 'eightoldstyle', 'nineoldstyle', 'colon', 'semicolon', 'commasuperior', + 'threequartersemdash', 'periodsuperior', 'asuperior', 'bsuperior', + 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', + 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', + 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', + 'parenrightinferior', 'hyphensuperior', 'colonmonetary', 'onefitted', + 'rupiah', 'centoldstyle', 'figuredash', 'hypheninferior', 'onequarter', + 'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths', + 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', + 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', + 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', + 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', + 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', + 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', + 'periodinferior', 'commainferior' ]; diff --git a/fonts.js b/fonts.js index 105df5ec6..7cd27f8b0 100644 --- a/fonts.js +++ b/fonts.js @@ -2586,7 +2586,7 @@ var Type2CFF = (function() { switch (format) { case 0: for (var i = 0; i < length; i++) { - var sid = (bytes[pos++] << 8) | bytes[pos++]; + var sid = (bytes[pos++] << 8) | bytes[pos++]; charset.push(strings[sid]); } break; @@ -2818,7 +2818,7 @@ var Type2CFF = (function() { start: start, end: end, data: bytes.subarray(start, end) - } + }; }, length: count, endPos: end From f08aafa72acf138421a8e5061fd78e240576181b Mon Sep 17 00:00:00 2001 From: Muhammad Fikri Date: Wed, 21 Sep 2011 11:49:09 +0700 Subject: [PATCH 09/39] add loading status --- web/viewer.css | 5 +++++ web/viewer.html | 3 ++- web/viewer.js | 11 +++++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/web/viewer.css b/web/viewer.css index d1f725a02..5b83c142a 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -271,3 +271,8 @@ canvas { page-break-after: always; } } + +#loading { + margin:100px 0; + text-align:center; +} diff --git a/web/viewer.html b/web/viewer.html index a53593df3..13d19fb6c 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -89,7 +89,8 @@ - + +
Loading... 0%
diff --git a/web/viewer.js b/web/viewer.js index 520cf4efa..87ed2b54f 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -110,13 +110,15 @@ var PDFView = { var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.mozResponseType = xhr.responseType = 'arraybuffer'; - xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; + xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; + xhr.onprogress=PDFView.progressLevel; xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === xhr.expected) { var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response); - + + document.getElementById('loading').style.display="none"; PDFView.load(data, scale); } }; @@ -124,6 +126,11 @@ var PDFView = { xhr.send(null); }, + progressLevel: function(evt) { + var p=Math.round((evt.loaded / evt.total)*100); + document.getElementById('loading').innerHTML = 'Loading... '+p+'%'; + }, + navigateTo: function(dest) { if (typeof dest === 'string') dest = this.destinations[dest]; From 34b64160175b80f68e125b7d83759b0c036cbbe8 Mon Sep 17 00:00:00 2001 From: Muhammad Fikri Date: Wed, 21 Sep 2011 19:25:29 +0700 Subject: [PATCH 10/39] fix indentations and style nits --- web/viewer.css | 4 ++-- web/viewer.html | 2 +- web/viewer.js | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/web/viewer.css b/web/viewer.css index 5b83c142a..cda191a76 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -273,6 +273,6 @@ canvas { } #loading { - margin:100px 0; - text-align:center; + margin: 100px 0; + text-align: center; } diff --git a/web/viewer.html b/web/viewer.html index 13d19fb6c..ecb869668 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -90,7 +90,7 @@ -
Loading... 0%
+
Loading... 0%
diff --git a/web/viewer.js b/web/viewer.js index 87ed2b54f..1a218c6dc 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -111,14 +111,14 @@ var PDFView = { xhr.open('GET', url); xhr.mozResponseType = xhr.responseType = 'arraybuffer'; xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; - xhr.onprogress=PDFView.progressLevel; + xhr.onprogress = PDFView.progressLevel; xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === xhr.expected) { var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response); - document.getElementById('loading').style.display="none"; + document.getElementById('loading').style.display = "none"; PDFView.load(data, scale); } }; @@ -127,8 +127,8 @@ var PDFView = { }, progressLevel: function(evt) { - var p=Math.round((evt.loaded / evt.total)*100); - document.getElementById('loading').innerHTML = 'Loading... '+p+'%'; + var p = Math.round((evt.loaded / evt.total) * 100); + document.getElementById('loading').innerHTML = 'Loading... ' + p + '%'; }, navigateTo: function(dest) { From 14bbd82ce53e861333a107c82fe5f8145f6fd284 Mon Sep 17 00:00:00 2001 From: Muhammad Fikri Date: Wed, 21 Sep 2011 21:05:40 +0700 Subject: [PATCH 11/39] fix indentation again --- web/viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/viewer.js b/web/viewer.js index 1a218c6dc..72b540664 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -118,7 +118,7 @@ var PDFView = { var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response); - document.getElementById('loading').style.display = "none"; + document.getElementById('loading').style.display = "none"; PDFView.load(data, scale); } }; From 826e0baf14df507665daff37e5dcce37ffdc69d6 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 21 Sep 2011 16:26:20 +0200 Subject: [PATCH 12/39] Fix a small lint error in fonts_utils.js --- utils/fonts_utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/fonts_utils.js b/utils/fonts_utils.js index ff5e686b5..550637fff 100644 --- a/utils/fonts_utils.js +++ b/utils/fonts_utils.js @@ -55,7 +55,7 @@ function readCharset(aStream, aCharstrings) { */ function readCharstringEncoding(aString) { if (!aString) - return ""; + return ''; var charstringTokens = []; From e318820a39eee9ae0b112772e5e33d0e668641a5 Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 21 Sep 2011 10:04:21 -0700 Subject: [PATCH 13/39] Ignore previously parsed xref streams --- pdf.js | 9 +++++---- test/pdfs/f1040.pdf.link | 1 + test/test_manifest.json | 6 ++++++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 test/pdfs/f1040.pdf.link diff --git a/pdf.js b/pdf.js index 224becdf1..9a0b0977a 100644 --- a/pdf.js +++ b/pdf.js @@ -3094,10 +3094,11 @@ var XRef = (function() { // check for 'XRefStm' key if (IsInt(obj = dict.get('XRefStm'))) { var pos = obj; - if (pos in this.xrefstms) - error('Invalid XRef table'); - this.xrefstms[pos] = 1; // avoid infinite recursion - this.readXRef(pos); + // ignore previously loaded xref streams (possible infinite recursion) + if (!(pos in this.xrefstms)) { + this.xrefstms[pos] = 1; + this.readXRef(pos); + } } return dict; diff --git a/test/pdfs/f1040.pdf.link b/test/pdfs/f1040.pdf.link new file mode 100644 index 000000000..a3299fc54 --- /dev/null +++ b/test/pdfs/f1040.pdf.link @@ -0,0 +1 @@ +http://www.irs.gov/pub/irs-pdf/f1040.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index a3115764a..edf13b7c5 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -139,5 +139,11 @@ "link": true, "rounds": 1, "type": "load" + }, + { "id": "f1040", + "file": "pdfs/f1040.pdf", + "link": true, + "rounds": 1, + "type": "load" } ] From de03b362cffe26a8d58cea00568259df2707cb1c Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Wed, 21 Sep 2011 23:46:29 +0300 Subject: [PATCH 14/39] Name anonymous functions. This makes profiling much more convenient. --- pdf.js | 445 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 233 insertions(+), 212 deletions(-) diff --git a/pdf.js b/pdf.js index 224becdf1..a0b8ac14b 100644 --- a/pdf.js +++ b/pdf.js @@ -61,7 +61,7 @@ function shadow(obj, prop, value) { configurable: true, writable: false }); } catch (e) { - obj.__defineGetter__(prop, function() { + obj.__defineGetter__(prop, function shadowDefineGetter() { return value; }); } @@ -112,7 +112,7 @@ function stringToPDFString(str) { return str2; } -var Stream = (function() { +var Stream = (function streamStream() { function constructor(arrayBuffer, start, length, dict) { this.bytes = new Uint8Array(arrayBuffer); this.start = start || 0; @@ -178,7 +178,7 @@ var Stream = (function() { return constructor; })(); -var StringStream = (function() { +var StringStream = (function stringStream() { function constructor(str) { var length = str.length; var bytes = new Uint8Array(length); @@ -193,7 +193,7 @@ var StringStream = (function() { })(); // super class for the decoding streams -var DecodeStream = (function() { +var DecodeStream = (function decodeStream() { function constructor() { this.pos = 0; this.bufferLength = 0; @@ -289,21 +289,21 @@ var DecodeStream = (function() { return constructor; })(); -var FakeStream = (function() { +var FakeStream = (function fakeStream() { function constructor(stream) { this.dict = stream.dict; DecodeStream.call(this); } constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function fakeStreamReadBlock() { var bufferLength = this.bufferLength; bufferLength += 1024; var buffer = this.ensureBuffer(bufferLength); this.bufferLength = bufferLength; }; - constructor.prototype.getBytes = function(length) { + constructor.prototype.getBytes = function fakeStreamGetBytes(length) { var end, pos = this.pos; if (length) { @@ -328,7 +328,7 @@ var FakeStream = (function() { return constructor; })(); -var StreamsSequenceStream = (function() { +var StreamsSequenceStream = (function streamSequenceStream() { function constructor(streams) { this.streams = streams; DecodeStream.call(this); @@ -336,7 +336,7 @@ var StreamsSequenceStream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function streamSequenceStreamReadBlock() { var streams = this.streams; if (streams.length == 0) { this.eof = true; @@ -354,7 +354,7 @@ var StreamsSequenceStream = (function() { return constructor; })(); -var FlateStream = (function() { +var FlateStream = (function flateStream() { var codeLenCodeMap = new Uint32Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]); @@ -474,7 +474,7 @@ var FlateStream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.getBits = function(bits) { + constructor.prototype.getBits = function flateStreamGetBits(bits) { var codeSize = this.codeSize; var codeBuf = this.codeBuf; var bytes = this.bytes; @@ -494,7 +494,7 @@ var FlateStream = (function() { return b; }; - constructor.prototype.getCode = function(table) { + constructor.prototype.getCode = function flateStreamGetCode(table) { var codes = table[0]; var maxLen = table[1]; var codeSize = this.codeSize; @@ -520,7 +520,8 @@ var FlateStream = (function() { return codeVal; }; - constructor.prototype.generateHuffmanTable = function(lengths) { + constructor.prototype.generateHuffmanTable = + function flateStreamGenerateHuffmanTable(lengths) { var n = lengths.length; // find max code length @@ -558,7 +559,7 @@ var FlateStream = (function() { return [codes, maxLen]; }; - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function flateStreamReadBlock() { // read block header var hdr = this.getBits(3); if (hdr & 1) @@ -692,7 +693,7 @@ var FlateStream = (function() { return constructor; })(); -var PredictorStream = (function() { +var PredictorStream = (function predictorStream() { function constructor(stream, params) { var predictor = this.predictor = params.get('Predictor') || 1; @@ -723,7 +724,8 @@ var PredictorStream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBlockTiff = function() { + constructor.prototype.readBlockTiff = + function predictorStreamReadBlockTiff() { var rowBytes = this.rowBytes; var bufferLength = this.bufferLength; @@ -783,7 +785,7 @@ var PredictorStream = (function() { this.bufferLength += rowBytes; }; - constructor.prototype.readBlockPng = function() { + constructor.prototype.readBlockPng = function predictorStreamReadBlockPng() { var rowBytes = this.rowBytes; var pixBytes = this.pixBytes; @@ -860,7 +862,7 @@ var PredictorStream = (function() { // A JpegStream can't be read directly. We use the platform to render // the underlying JPEG data for us. -var JpegStream = (function() { +var JpegStream = (function jpegStream() { function isYcckImage(bytes) { var maxBytesScanned = Math.max(bytes.length - 16, 1024); // Looking for APP14, 'Adobe' and transform = 2 @@ -901,7 +903,7 @@ var JpegStream = (function() { // create DOM image var img = new Image(); - img.onload = (function() { + img.onload = (function jpegStreamOnload() { this.loaded = true; if (this.onLoad) this.onLoad(); @@ -911,10 +913,10 @@ var JpegStream = (function() { } constructor.prototype = { - getImage: function() { + getImage: function jpegStreamGetImage() { return this.domImage; }, - getChar: function() { + getChar: function jpegStreamGetChar() { error('internal error: getChar is not valid on JpegStream'); } }; @@ -926,31 +928,31 @@ var JpegStream = (function() { // Initialy for every that is in loading call imageLoading() // and, when images onload is fired, call imageLoaded() // When all images are loaded, the onLoad event is fired. -var ImagesLoader = (function() { +var ImagesLoader = (function imagesLoader() { function constructor() { this.loading = 0; } constructor.prototype = { - imageLoading: function() { + imageLoading: function imagesLoaderImageLoading() { ++this.loading; }, - imageLoaded: function() { + imageLoaded: function imagesLoaderImageLoaded() { if (--this.loading == 0 && this.onLoad) { this.onLoad(); delete this.onLoad; } }, - bind: function(jpegStream) { + bind: function imagesLoaderBind(jpegStream) { if (jpegStream.loaded) return; this.imageLoading(); jpegStream.onLoad = this.imageLoaded.bind(this); }, - notifyOnLoad: function(callback) { + notifyOnLoad: function imagesLoaderNotifyOnLoad(callback) { if (this.loading == 0) callback(); this.onLoad = callback; @@ -960,7 +962,7 @@ var ImagesLoader = (function() { return constructor; })(); -var DecryptStream = (function() { +var DecryptStream = (function decryptStream() { function constructor(str, decrypt) { this.str = str; this.dict = str.dict; @@ -973,7 +975,7 @@ var DecryptStream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function decryptStreamReadBlock() { var chunk = this.str.getBytes(chunkSize); if (!chunk || chunk.length == 0) { this.eof = true; @@ -993,7 +995,7 @@ var DecryptStream = (function() { return constructor; })(); -var Ascii85Stream = (function() { +var Ascii85Stream = (function ascii85Stream() { function constructor(str) { this.str = str; this.dict = str.dict; @@ -1004,7 +1006,7 @@ var Ascii85Stream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function ascii85StreamReadBlock() { var tildaCode = '~'.charCodeAt(0); var zCode = 'z'.charCodeAt(0); var str = this.str; @@ -1062,7 +1064,7 @@ var Ascii85Stream = (function() { return constructor; })(); -var AsciiHexStream = (function() { +var AsciiHexStream = (function asciiHexStream() { function constructor(str) { this.str = str; this.dict = str.dict; @@ -1099,7 +1101,7 @@ var AsciiHexStream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function asciiHexStreamReadBlock() { var gtCode = '>'.charCodeAt(0), bytes = this.str.getBytes(), c, n, decodeLength, buffer, bufferLength, i, length; @@ -1132,7 +1134,7 @@ var AsciiHexStream = (function() { return constructor; })(); -var CCITTFaxStream = (function() { +var CCITTFaxStream = (function cCITTFaxStream() { var ccittEOL = -2; var twoDimPass = 0; @@ -1607,7 +1609,7 @@ var CCITTFaxStream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function cCITTFaxStreamReadBlock() { while (!this.eof) { var c = this.lookChar(); this.buf = EOF; @@ -1616,7 +1618,8 @@ var CCITTFaxStream = (function() { } }; - constructor.prototype.addPixels = function(a1, blackPixels) { + constructor.prototype.addPixels = + function cCITTFaxStreamAddPixels(a1, blackPixels) { var codingLine = this.codingLine; var codingPos = this.codingPos; @@ -1635,7 +1638,8 @@ var CCITTFaxStream = (function() { this.codingPos = codingPos; }; - constructor.prototype.addPixelsNeg = function(a1, blackPixels) { + constructor.prototype.addPixelsNeg = + function cCITTFaxStreamAddPixelsNeg(a1, blackPixels) { var codingLine = this.codingLine; var codingPos = this.codingPos; @@ -1663,7 +1667,7 @@ var CCITTFaxStream = (function() { this.codingPos = codingPos; }; - constructor.prototype.lookChar = function() { + constructor.prototype.lookChar = function cCITTFaxStreamLookChar() { if (this.buf != EOF) return this.buf; @@ -1955,7 +1959,7 @@ var CCITTFaxStream = (function() { return this.buf; }; - constructor.prototype.getTwoDimCode = function() { + constructor.prototype.getTwoDimCode = function cCITTFaxStreamGetTwoDimCode() { var code = 0; var p; if (this.eoblock) { @@ -1982,7 +1986,7 @@ var CCITTFaxStream = (function() { return EOF; }; - constructor.prototype.getWhiteCode = function() { + constructor.prototype.getWhiteCode = function cCITTFaxStreamGetWhiteCode() { var code = 0; var p; var n; @@ -2032,7 +2036,7 @@ var CCITTFaxStream = (function() { return 1; }; - constructor.prototype.getBlackCode = function() { + constructor.prototype.getBlackCode = function cCITTFaxStreamGetBlackCode() { var code, p; if (this.eoblock) { code = this.lookBits(13); @@ -2095,7 +2099,7 @@ var CCITTFaxStream = (function() { return 1; }; - constructor.prototype.lookBits = function(n) { + constructor.prototype.lookBits = function cCITTFaxStreamLookBits(n) { var c; while (this.inputBits < n) { if ((c = this.str.getByte()) == null) { @@ -2110,7 +2114,7 @@ var CCITTFaxStream = (function() { return (this.inputBuf >> (this.inputBits - n)) & (0xFFFF >> (16 - n)); }; - constructor.prototype.eatBits = function(n) { + constructor.prototype.eatBits = function cCITTFaxStreamEatBits(n) { if ((this.inputBits -= n) < 0) this.inputBits = 0; }; @@ -2118,7 +2122,7 @@ var CCITTFaxStream = (function() { return constructor; })(); -var LZWStream = (function() { +var LZWStream = (function lZWStream() { function constructor(str, earlyChange) { this.str = str; this.dict = str.dict; @@ -2147,7 +2151,7 @@ var LZWStream = (function() { constructor.prototype = Object.create(DecodeStream.prototype); - constructor.prototype.readBits = function(n) { + constructor.prototype.readBits = function lZWStreamReadBits(n) { var bitsCached = this.bitsCached; var cachedData = this.cachedData; while (bitsCached < n) { @@ -2165,7 +2169,7 @@ var LZWStream = (function() { return (cachedData >>> bitsCached) & ((1 << n) - 1); }; - constructor.prototype.readBlock = function() { + constructor.prototype.readBlock = function lZWStreamReadBlock() { var blockSize = 512; var estimatedDecodedSize = blockSize * 2, decodedSizeDelta = blockSize; var i, j, q; @@ -2248,7 +2252,7 @@ var LZWStream = (function() { })(); -var Name = (function() { +var Name = (function nameName() { function constructor(name) { this.name = name; } @@ -2259,7 +2263,7 @@ var Name = (function() { return constructor; })(); -var Cmd = (function() { +var Cmd = (function cmdCmd() { function constructor(cmd) { this.cmd = cmd; } @@ -2270,13 +2274,13 @@ var Cmd = (function() { return constructor; })(); -var Dict = (function() { +var Dict = (function dictDict() { function constructor() { this.map = Object.create(null); } constructor.prototype = { - get: function(key1, key2, key3) { + get: function dictGet(key1, key2, key3) { var value; if (typeof (value = this.map[key1]) != 'undefined' || key1 in this.map || typeof key2 == 'undefined') { @@ -2290,15 +2294,15 @@ var Dict = (function() { return this.map[key3] || null; }, - set: function(key, value) { + set: function dictSet(key, value) { this.map[key] = value; }, - has: function(key) { + has: function dictHas(key) { return key in this.map; }, - forEach: function(callback) { + forEach: function dictForEach(callback) { for (var key in this.map) { callback(key, this.map[key]); } @@ -2308,7 +2312,7 @@ var Dict = (function() { return constructor; })(); -var Ref = (function() { +var Ref = (function refRef() { function constructor(num, gen) { this.num = num; this.gen = gen; @@ -2322,17 +2326,17 @@ var Ref = (function() { // The reference is identified by number and generation, // this structure stores only one instance of the reference. -var RefSet = (function() { +var RefSet = (function refSet() { function constructor() { this.dict = {}; } constructor.prototype = { - has: function(ref) { + has: function refSetHas(ref) { return !!this.dict['R' + ref.num + '.' + ref.gen]; }, - put: function(ref) { + put: function refSetPut(ref) { this.dict['R' + ref.num + '.' + ref.gen] = ref; } }; @@ -2409,12 +2413,12 @@ function IsNone(v) { return v == None; } -var Lexer = (function() { +var Lexer = (function lexer() { function constructor(stream) { this.stream = stream; } - constructor.isSpace = function(ch) { + constructor.isSpace = function lexerIsSpace(ch) { return ch == ' ' || ch == '\t' || ch == '\x0d' || ch == '\x0a'; }; @@ -2449,7 +2453,7 @@ var Lexer = (function() { } constructor.prototype = { - getNumber: function(ch) { + getNumber: function lexerGetNumber(ch) { var floating = false; var str = ch; var stream = this.stream; @@ -2477,7 +2481,7 @@ var Lexer = (function() { error('Invalid floating point number: ' + value); return value; }, - getString: function() { + getString: function lexerGetString() { var numParen = 1; var done = false; var str = ''; @@ -2561,7 +2565,7 @@ var Lexer = (function() { } while (!done); return str; }, - getName: function(ch) { + getName: function lexerGetName(ch) { var str = ''; var stream = this.stream; while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) { @@ -2588,7 +2592,7 @@ var Lexer = (function() { str.length); return new Name(str); }, - getHexString: function(ch) { + getHexString: function lexerGetHexString(ch) { var str = ''; var stream = this.stream; for (;;) { @@ -2617,7 +2621,7 @@ var Lexer = (function() { } return str; }, - getObj: function() { + getObj: function lexerGetObj() { // skip whitespace and comments var comment = false; var stream = this.stream; @@ -2692,7 +2696,7 @@ var Lexer = (function() { return null; return new Cmd(str); }, - skipToNextLine: function() { + skipToNextLine: function lexerSkipToNextLine() { var stream = this.stream; while (true) { var ch = stream.getChar(); @@ -2705,7 +2709,7 @@ var Lexer = (function() { } } }, - skip: function() { + skip: function lexerSkip() { this.stream.skip(); } }; @@ -2713,7 +2717,7 @@ var Lexer = (function() { return constructor; })(); -var Parser = (function() { +var Parser = (function parserParser() { function constructor(lexer, allowStreams, xref) { this.lexer = lexer; this.allowStreams = allowStreams; @@ -2723,11 +2727,11 @@ var Parser = (function() { } constructor.prototype = { - refill: function() { + refill: function parserRefill() { this.buf1 = this.lexer.getObj(); this.buf2 = this.lexer.getObj(); }, - shift: function() { + shift: function parserShift() { if (IsCmd(this.buf2, 'ID')) { this.buf1 = this.buf2; this.buf2 = null; @@ -2738,7 +2742,7 @@ var Parser = (function() { this.buf2 = this.lexer.getObj(); } }, - getObj: function(cipherTransform) { + getObj: function parserGetObj(cipherTransform) { if (IsCmd(this.buf1, 'BI')) { // inline image this.shift(); return this.makeInlineImage(cipherTransform); @@ -2800,7 +2804,7 @@ var Parser = (function() { this.shift(); return obj; }, - makeInlineImage: function(cipherTransform) { + makeInlineImage: function parserMakeInlineImage(cipherTransform) { var lexer = this.lexer; var stream = lexer.stream; @@ -2840,7 +2844,7 @@ var Parser = (function() { return imageStream; }, - makeStream: function(dict, cipherTransform) { + makeStream: function parserMakeStream(dict, cipherTransform) { var lexer = this.lexer; var stream = lexer.stream; @@ -2873,7 +2877,7 @@ var Parser = (function() { stream.parameters = dict; return stream; }, - filter: function(stream, dict, length) { + filter: function parserFilter(stream, dict, length) { var filter = dict.get('Filter', 'F'); var params = dict.get('DecodeParms', 'DP'); if (IsName(filter)) @@ -2897,7 +2901,7 @@ var Parser = (function() { } return stream; }, - makeFilter: function(stream, name, length, params) { + makeFilter: function parserMakeFilter(stream, name, length, params) { if (name == 'FlateDecode' || name == 'Fl') { if (params) { return new PredictorStream(new FlateStream(stream), params); @@ -2931,7 +2935,7 @@ var Parser = (function() { return constructor; })(); -var Linearization = (function() { +var Linearization = (function linearizationLinearization() { function constructor(stream) { this.parser = new Parser(new Lexer(stream), false); var obj1 = this.parser.getObj(); @@ -2947,7 +2951,7 @@ var Linearization = (function() { } constructor.prototype = { - getInt: function(name) { + getInt: function linearizationGetInt(name) { var linDict = this.linDict; var obj; if (IsDict(linDict) && @@ -2958,7 +2962,7 @@ var Linearization = (function() { error('"' + name + '" field in linearization table is invalid'); return 0; }, - getHint: function(index) { + getHint: function linearizationGetHint(index) { var linDict = this.linDict; var obj1, obj2; if (IsDict(linDict) && @@ -3008,7 +3012,7 @@ var Linearization = (function() { return constructor; })(); -var XRef = (function() { +var XRef = (function xRefXRef() { function constructor(stream, startXRef, mainXRefEntriesOffset) { this.stream = stream; this.entries = []; @@ -3176,18 +3180,18 @@ var XRef = (function() { error('Invalid XRef'); return null; }, - getEntry: function(i) { + getEntry: function xRefGetEntry(i) { var e = this.entries[i]; if (e.free) error('reading an XRef stream not implemented yet'); return e; }, - fetchIfRef: function(obj) { + fetchIfRef: function xRefFetchIfRef(obj) { if (!IsRef(obj)) return obj; return this.fetch(obj); }, - fetch: function(ref, suppressEncryption) { + fetch: function xRefFetch(ref, suppressEncryption) { var num = ref.num; var e = this.cache[num]; if (e) @@ -3270,7 +3274,7 @@ var XRef = (function() { } return e; }, - getCatalogObj: function() { + getCatalogObj: function xRefGetCatalogObj() { return this.fetch(this.root); } }; @@ -3278,7 +3282,7 @@ var XRef = (function() { return constructor; })(); -var Page = (function() { +var Page = (function pagePage() { function constructor(xref, pageNumber, pageDict, ref) { this.pageNumber = pageNumber; this.pageDict = pageDict; @@ -3294,10 +3298,10 @@ var Page = (function() { } constructor.prototype = { - getPageProp: function(key) { + getPageProp: function pageGetPageProp(key) { return this.xref.fetchIfRef(this.pageDict.get(key)); }, - inheritPageProp: function(key) { + inheritPageProp: function pageInheritPageProp(key) { var dict = this.pageDict; var obj = dict.get(key); while (obj === undefined) { @@ -3358,7 +3362,7 @@ var Page = (function() { } return shadow(this, 'rotate', rotate); }, - startRendering: function(canvasCtx, continuation) { + startRendering: function pageStartRendering(canvasCtx, continuation) { var self = this; var stats = self.stats; stats.compile = stats.fonts = stats.render = 0; @@ -3370,10 +3374,10 @@ var Page = (function() { this.compile(gfx, fonts, images); stats.compile = Date.now(); - var displayContinuation = function() { + var displayContinuation = function pageDisplayContinuation() { // Always defer call to display() to work around bug in // Firefox error reporting from XHR callbacks. - setTimeout(function() { + setTimeout(function pageSetTimeout() { var exc = null; try { self.display(gfx); @@ -3387,9 +3391,9 @@ var Page = (function() { var fontObjs = FontLoader.bind( fonts, - function() { + function pageFontObjs() { stats.fonts = Date.now(); - images.notifyOnLoad(function() { + images.notifyOnLoad(function pageNotifyOnLoad() { stats.images = Date.now(); displayContinuation(); }); @@ -3400,7 +3404,7 @@ var Page = (function() { }, - compile: function(gfx, fonts, images) { + compile: function pageCompile(gfx, fonts, images) { if (this.code) { // content was compiled return; @@ -3418,7 +3422,7 @@ var Page = (function() { } this.code = gfx.compile(content, xref, resources, fonts, images); }, - display: function(gfx) { + display: function pageDisplay(gfx) { assert(this.code instanceof Function, 'page content must be compiled first'); var xref = this.xref; @@ -3432,7 +3436,7 @@ var Page = (function() { gfx.execute(this.code, xref, resources); gfx.endDrawing(); }, - rotatePoint: function(x, y) { + rotatePoint: function pageRotatePoint(x, y) { var rotate = this.rotate; switch (rotate) { case 180: @@ -3446,7 +3450,7 @@ var Page = (function() { return {x: x, y: this.height - y}; } }, - getLinks: function() { + getLinks: function pageGetLinks() { var xref = this.xref; var annotations = xref.fetchIfRef(this.annotations) || []; var i, n = annotations.length; @@ -3493,7 +3497,7 @@ var Page = (function() { return constructor; })(); -var Catalog = (function() { +var Catalog = (function catalogCatalog() { function constructor(xref) { this.xref = xref; var obj = xref.getCatalogObj(); @@ -3571,7 +3575,7 @@ var Catalog = (function() { // shadow the prototype getter return shadow(this, 'num', obj); }, - traverseKids: function(pagesDict) { + traverseKids: function catalogTraverseKids(pagesDict) { var pageCache = this.pageCache; var kids = pagesDict.get('Kids'); assertWellFormed(IsArray(kids), @@ -3609,7 +3613,7 @@ var Catalog = (function() { if (nameDictionaryRef) { // reading simple destination dictionary obj = xref.fetchIfRef(nameDictionaryRef); - obj.forEach(function(key, value) { + obj.forEach(function catalogForEach(key, value) { if (!value) return; dests[key] = fetchDestination(xref, value); }); @@ -3641,7 +3645,7 @@ var Catalog = (function() { } return shadow(this, 'destinations', dests); }, - getPage: function(n) { + getPage: function catalogGetPage(n) { var pageCache = this.pageCache; if (!pageCache) { pageCache = this.pageCache = []; @@ -3654,7 +3658,7 @@ var Catalog = (function() { return constructor; })(); -var PDFDoc = (function() { +var PDFDoc = (function pDFDoc() { function constructor(stream) { assertWellFormed(stream.length > 0, 'stream must have data'); this.stream = stream; @@ -3733,7 +3737,7 @@ var PDFDoc = (function() { }, // Find the header, remove leading garbage and setup the stream // starting from the header. - checkHeader: function() { + checkHeader: function pDFDocCheckHeader() { var stream = this.stream; stream.reset(); if (find(stream, '%PDF-', 1024)) { @@ -3743,7 +3747,7 @@ var PDFDoc = (function() { } // May not be a PDF file, continue anyway. }, - setup: function(ownerPassword, userPassword) { + setup: function pDFDocSetup(ownerPassword, userPassword) { this.checkHeader(); this.xref = new XRef(this.stream, this.startXRef, @@ -3756,7 +3760,7 @@ var PDFDoc = (function() { // shadow the prototype getter return shadow(this, 'numPages', num); }, - getPage: function(n) { + getPage: function pDFDocGetPage(n) { return this.catalog.getPage(n); } }; @@ -4031,7 +4035,7 @@ var Encodings = { var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; -var EvalState = (function() { +var EvalState = (function evalState() { function constructor() { // Are soft masks and alpha values shapes or opacities? this.alphaIsShape = false; @@ -4054,7 +4058,7 @@ var EvalState = (function() { return constructor; })(); -var PartialEvaluator = (function() { +var PartialEvaluator = (function partialEvaluator() { function constructor() { this.state = new EvalState(); this.stateStack = []; @@ -4158,7 +4162,8 @@ var PartialEvaluator = (function() { }; constructor.prototype = { - evaluate: function(stream, xref, resources, fonts, images) { + evaluate: function partialEvaluatorEvaluate(stream, xref, resources, fonts, + images) { resources = xref.fetchIfRef(resources) || new Dict(); var xobjs = xref.fetchIfRef(resources.get('XObject')) || new Dict(); var patterns = xref.fetchIfRef(resources.get('Pattern')) || new Dict(); @@ -4236,13 +4241,15 @@ var PartialEvaluator = (function() { } } - return function(gfx) { + return function partialEvaluatorReturn(gfx) { for (var i = 0, length = argsArray.length; i < length; i++) gfx[fnArray[i]].apply(gfx, argsArray[i]); }; }, - extractEncoding: function(dict, xref, properties) { + extractEncoding: function partialEvaluatorExtractEncoding(dict, + xref, + properties) { var type = properties.type, encoding; if (properties.composite) { if (type == 'CIDFontType2') { @@ -4482,7 +4489,8 @@ var PartialEvaluator = (function() { return glyphs; }, - translateFont: function(dict, xref, resources) { + translateFont: function partialEvaluatorTranslateFont(dict, xref, + resources) { var baseDict = dict; var type = dict.get('Subtype'); assertWellFormed(IsName(type), 'invalid font Subtype'); @@ -4603,7 +4611,7 @@ var PartialEvaluator = (function() { flags: descriptor.get('Flags'), italicAngle: descriptor.get('ItalicAngle'), differences: [], - widths: (function() { + widths: (function partialEvaluatorWidths() { var glyphWidths = {}; for (var i = 0; i < widths.length; i++) glyphWidths[firstChar++] = widths[i]; @@ -4627,7 +4635,7 @@ var PartialEvaluator = (function() { // contexts store most of the state we need natively. // However, PDF needs a bit more state, which we store here. -var CanvasExtraState = (function() { +var CanvasExtraState = (function canvasExtraState() { function constructor(old) { // Are soft masks and alpha values shapes or opacities? this.alphaIsShape = false; @@ -4672,7 +4680,7 @@ function ScratchCanvas(width, height) { return canvas; } -var CanvasGraphics = (function() { +var CanvasGraphics = (function canvasGraphics() { function constructor(canvasCtx, imageCanvas) { this.ctx = canvasCtx; this.current = new CanvasExtraState(); @@ -4689,7 +4697,7 @@ var CanvasGraphics = (function() { var EO_CLIP = {}; constructor.prototype = { - beginDrawing: function(mediaBox) { + beginDrawing: function canvasGraphicsBeginDrawing(mediaBox) { var cw = this.ctx.canvas.width, ch = this.ctx.canvas.height; this.ctx.save(); switch (mediaBox.rotate) { @@ -4709,12 +4717,13 @@ var CanvasGraphics = (function() { this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height); }, - compile: function(stream, xref, resources, fonts, images) { + compile: function canvasGraphicsCompile(stream, xref, resources, fonts, + images) { var pe = new PartialEvaluator(); return pe.evaluate(stream, xref, resources, fonts, images); }, - execute: function(code, xref, resources) { + execute: function canvasGraphicsExecute(code, xref, resources) { resources = xref.fetchIfRef(resources) || new Dict(); var savedXref = this.xref, savedRes = this.res, savedXobjs = this.xobjs; this.xref = xref; @@ -4728,37 +4737,37 @@ var CanvasGraphics = (function() { this.xref = savedXref; }, - endDrawing: function() { + endDrawing: function canvasGraphicsEndDrawing() { this.ctx.restore(); }, // Graphics state - setLineWidth: function(width) { + setLineWidth: function canvasGraphicsSetLineWidth(width) { this.ctx.lineWidth = width; }, - setLineCap: function(style) { + setLineCap: function canvasGraphicsSetLineCap(style) { this.ctx.lineCap = LINE_CAP_STYLES[style]; }, - setLineJoin: function(style) { + setLineJoin: function canvasGraphicsSetLineJoin(style) { this.ctx.lineJoin = LINE_JOIN_STYLES[style]; }, - setMiterLimit: function(limit) { + setMiterLimit: function canvasGraphicsSetMiterLimit(limit) { this.ctx.miterLimit = limit; }, - setDash: function(dashArray, dashPhase) { + setDash: function canvasGraphicsSetDash(dashArray, dashPhase) { this.ctx.mozDash = dashArray; this.ctx.mozDashOffset = dashPhase; }, - setRenderingIntent: function(intent) { + setRenderingIntent: function canvasGraphicsSetRenderingIntent(intent) { TODO('set rendering intent: ' + intent); }, - setFlatness: function(flatness) { + setFlatness: function canvasGraphicsSetFlatness(flatness) { TODO('set flatness: ' + flatness); }, - setGState: function(dictName) { + setGState: function canvasGraphicsSetGState(dictName) { TODO('set graphics state from dict: ' + dictName); }, - save: function() { + save: function canvasGraphicsSave() { this.ctx.save(); if (this.ctx.$saveCurrentX) { this.ctx.$saveCurrentX(); @@ -4767,7 +4776,7 @@ var CanvasGraphics = (function() { this.stateStack.push(old); this.current = old.clone(); }, - restore: function() { + restore: function canvasGraphicsRestore() { var prev = this.stateStack.pop(); if (prev) { if (this.ctx.$restoreCurrentX) { @@ -4777,39 +4786,39 @@ var CanvasGraphics = (function() { this.ctx.restore(); } }, - transform: function(a, b, c, d, e, f) { + transform: function canvasGraphicsTransform(a, b, c, d, e, f) { this.ctx.transform(a, b, c, d, e, f); }, // Path - moveTo: function(x, y) { + moveTo: function canvasGraphicsMoveTo(x, y) { this.ctx.moveTo(x, y); this.current.setCurrentPoint(x, y); }, - lineTo: function(x, y) { + lineTo: function canvasGraphicsLineTo(x, y) { this.ctx.lineTo(x, y); this.current.setCurrentPoint(x, y); }, - curveTo: function(x1, y1, x2, y2, x3, y3) { + curveTo: function canvasGraphicsCurveTo(x1, y1, x2, y2, x3, y3) { this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); this.current.setCurrentPoint(x3, y3); }, - curveTo2: function(x2, y2, x3, y3) { + curveTo2: function canvasGraphicsCurveTo2(x2, y2, x3, y3) { var current = this.current; this.ctx.bezierCurveTo(current.x, current.y, x2, y2, x3, y3); current.setCurrentPoint(x3, y3); }, - curveTo3: function(x1, y1, x3, y3) { + curveTo3: function canvasGraphicsCurveTo3(x1, y1, x3, y3) { this.curveTo(x1, y1, x3, y3, x3, y3); this.current.setCurrentPoint(x3, y3); }, - closePath: function() { + closePath: function canvasGraphicsClosePath() { this.ctx.closePath(); }, - rectangle: function(x, y, width, height) { + rectangle: function canvasGraphicsRectangle(x, y, width, height) { this.ctx.rect(x, y, width, height); }, - stroke: function() { + stroke: function canvasGraphicsStroke() { var ctx = this.ctx; var strokeColor = this.current.strokeColor; if (strokeColor && strokeColor.type === 'Pattern') { @@ -4825,11 +4834,11 @@ var CanvasGraphics = (function() { this.consumePath(); }, - closeStroke: function() { + closeStroke: function canvasGraphicsCloseStroke() { this.closePath(); this.stroke(); }, - fill: function() { + fill: function canvasGraphicsFill() { var ctx = this.ctx; var fillColor = this.current.fillColor; @@ -4844,12 +4853,12 @@ var CanvasGraphics = (function() { this.consumePath(); }, - eoFill: function() { + eoFill: function canvasGraphicsEoFill() { var savedFillRule = this.setEOFillRule(); this.fill(); this.restoreFillRule(savedFillRule); }, - fillStroke: function() { + fillStroke: function canvasGraphicsFillStroke() { var ctx = this.ctx; var fillColor = this.current.fillColor; @@ -4874,33 +4883,33 @@ var CanvasGraphics = (function() { this.consumePath(); }, - eoFillStroke: function() { + eoFillStroke: function canvasGraphicsEoFillStroke() { var savedFillRule = this.setEOFillRule(); this.fillStroke(); this.restoreFillRule(savedFillRule); }, - closeFillStroke: function() { + closeFillStroke: function canvasGraphicsCloseFillStroke() { return this.fillStroke(); }, - closeEOFillStroke: function() { + closeEOFillStroke: function canvasGraphicsCloseEOFillStroke() { var savedFillRule = this.setEOFillRule(); this.fillStroke(); this.restoreFillRule(savedFillRule); }, - endPath: function() { + endPath: function canvasGraphicsEndPath() { this.consumePath(); }, // Clipping - clip: function() { + clip: function canvasGraphicsClip() { this.pendingClip = NORMAL_CLIP; }, - eoClip: function() { + eoClip: function canvasGraphicsEoClip() { this.pendingClip = EO_CLIP; }, // Text - beginText: function() { + beginText: function canvasGraphicsBeginText() { this.current.textMatrix = IDENTITY_MATRIX; if (this.ctx.$setCurrentX) { this.ctx.$setCurrentX(0); @@ -4908,21 +4917,21 @@ var CanvasGraphics = (function() { this.current.x = this.current.lineX = 0; this.current.y = this.current.lineY = 0; }, - endText: function() { + endText: function canvasGraphicsEndText() { }, - setCharSpacing: function(spacing) { + setCharSpacing: function canvasGraphicsSetCharSpacing(spacing) { this.current.charSpacing = spacing; }, - setWordSpacing: function(spacing) { + setWordSpacing: function canvasGraphicsSetWordSpacing(spacing) { this.current.wordSpacing = spacing; }, - setHScale: function(scale) { + setHScale: function canvasGraphicsSetHScale(scale) { this.current.textHScale = scale / 100; }, - setLeading: function(leading) { + setLeading: function canvasGraphicsSetLeading(leading) { this.current.leading = -leading; }, - setFont: function(fontRef, size) { + setFont: function canvasGraphicsSetFont(fontRef, size) { var font = this.xref.fetchIfRef(this.res.get('Font')); if (!IsDict(font)) return; @@ -4950,24 +4959,24 @@ var CanvasGraphics = (function() { this.ctx.font = rule; } }, - setTextRenderingMode: function(mode) { + setTextRenderingMode: function canvasGraphicsSetTextRenderingMode(mode) { TODO('text rendering mode: ' + mode); }, - setTextRise: function(rise) { + setTextRise: function canvasGraphicsSetTextRise(rise) { TODO('text rise: ' + rise); }, - moveText: function(x, y) { + moveText: function canvasGraphicsMoveText(x, y) { this.current.x = this.current.lineX += x; this.current.y = this.current.lineY += y; if (this.ctx.$setCurrentX) { this.ctx.$setCurrentX(this.current.x); } }, - setLeadingMoveText: function(x, y) { + setLeadingMoveText: function canvasGraphicsSetLeadingMoveText(x, y) { this.setLeading(-y); this.moveText(x, y); }, - setTextMatrix: function(a, b, c, d, e, f) { + setTextMatrix: function canvasGraphicsSetTextMatrix(a, b, c, d, e, f) { this.current.textMatrix = [a, b, c, d, e, f]; if (this.ctx.$setCurrentX) { @@ -4976,10 +4985,10 @@ var CanvasGraphics = (function() { this.current.x = this.current.lineX = 0; this.current.y = this.current.lineY = 0; }, - nextLine: function() { + nextLine: function canvasGraphicsNextLine() { this.moveText(0, this.current.leading); }, - showText: function(text) { + showText: function canvasGraphicsShowText(text) { var ctx = this.ctx; var current = this.current; var font = current.font; @@ -5021,7 +5030,7 @@ var CanvasGraphics = (function() { this.ctx.restore(); }, - showSpacedText: function(arr) { + showSpacedText: function canvasGraphicsShowSpacedText(arr) { for (var i = 0; i < arr.length; ++i) { var e = arr[i]; if (IsNum(e)) { @@ -5038,42 +5047,50 @@ var CanvasGraphics = (function() { } } }, - nextLineShowText: function(text) { + nextLineShowText: function canvasGraphicsNextLineShowText(text) { this.nextLine(); this.showText(text); }, - nextLineSetSpacingShowText: function(wordSpacing, charSpacing, text) { + nextLineSetSpacingShowText: + function canvasGraphicsNextLineSetSpacingShowText(wordSpacing, + charSpacing, + text) { this.setWordSpacing(wordSpacing); this.setCharSpacing(charSpacing); this.nextLineShowText(text); }, // Type3 fonts - setCharWidth: function(xWidth, yWidth) { + setCharWidth: function canvasGraphicsSetCharWidth(xWidth, yWidth) { TODO('type 3 fonts ("d0" operator) xWidth: ' + xWidth + ' yWidth: ' + yWidth); }, - setCharWidthAndBounds: function(xWidth, yWidth, llx, lly, urx, ury) { + setCharWidthAndBounds: function canvasGraphicsSetCharWidthAndBounds(xWidth, + yWidth, + llx, + lly, + urx, + ury) { TODO('type 3 fonts ("d1" operator) xWidth: ' + xWidth + ' yWidth: ' + yWidth + ' llx: ' + llx + ' lly: ' + lly + ' urx: ' + urx + ' ury ' + ury); }, // Color - setStrokeColorSpace: function(space) { + setStrokeColorSpace: function canvasGraphicsSetStrokeColorSpace(space) { this.current.strokeColorSpace = ColorSpace.parse(space, this.xref, this.res); }, - setFillColorSpace: function(space) { + setFillColorSpace: function canvasGraphicsSetFillColorSpace(space) { this.current.fillColorSpace = ColorSpace.parse(space, this.xref, this.res); }, - setStrokeColor: function(/*...*/) { + setStrokeColor: function canvasGraphicsSetStrokeColor(/*...*/) { var cs = this.current.strokeColorSpace; var color = cs.getRgb(arguments); this.setStrokeRGBColor.apply(this, color); }, - setStrokeColorN: function(/*...*/) { + setStrokeColorN: function canvasGraphicsSetStrokeColorN(/*...*/) { var cs = this.current.strokeColorSpace; if (cs.name == 'Pattern') { @@ -5087,12 +5104,12 @@ var CanvasGraphics = (function() { this.setStrokeColor.apply(this, arguments); } }, - setFillColor: function(/*...*/) { + setFillColor: function canvasGraphicsSetFillColor(/*...*/) { var cs = this.current.fillColorSpace; var color = cs.getRgb(arguments); this.setFillRGBColor.apply(this, color); }, - setFillColorN: function(/*...*/) { + setFillColorN: function canvasGraphicsSetFillColorN(/*...*/) { var cs = this.current.fillColorSpace; if (cs.name == 'Pattern') { @@ -5104,35 +5121,35 @@ var CanvasGraphics = (function() { this.setFillColor.apply(this, arguments); } }, - setStrokeGray: function(gray) { + setStrokeGray: function canvasGraphicsSetStrokeGray(gray) { this.setStrokeRGBColor(gray, gray, gray); }, - setFillGray: function(gray) { + setFillGray: function canvasGraphicsSetFillGray(gray) { this.setFillRGBColor(gray, gray, gray); }, - setStrokeRGBColor: function(r, g, b) { + setStrokeRGBColor: function canvasGraphicsSetStrokeRGBColor(r, g, b) { var color = Util.makeCssRgb(r, g, b); this.ctx.strokeStyle = color; this.current.strokeColor = color; }, - setFillRGBColor: function(r, g, b) { + setFillRGBColor: function canvasGraphicsSetFillRGBColor(r, g, b) { var color = Util.makeCssRgb(r, g, b); this.ctx.fillStyle = color; this.current.fillColor = color; }, - setStrokeCMYKColor: function(c, m, y, k) { + setStrokeCMYKColor: function canvasGraphicsSetStrokeCMYKColor(c, m, y, k) { var color = Util.makeCssCmyk(c, m, y, k); this.ctx.strokeStyle = color; this.current.strokeColor = color; }, - setFillCMYKColor: function(c, m, y, k) { + setFillCMYKColor: function canvasGraphicsSetFillCMYKColor(c, m, y, k) { var color = Util.makeCssCmyk(c, m, y, k); this.ctx.fillStyle = color; this.current.fillColor = color; }, // Shading - shadingFill: function(shadingName) { + shadingFill: function canvasGraphicsShadingFill(shadingName) { var xref = this.xref; var res = this.res; var ctx = this.ctx; @@ -5181,18 +5198,18 @@ var CanvasGraphics = (function() { }, // Images - beginInlineImage: function() { + beginInlineImage: function canvasGraphicsBeginInlineImage() { error('Should not call beginInlineImage'); }, - beginImageData: function() { + beginImageData: function canvasGraphicsBeginImageData() { error('Should not call beginImageData'); }, - endInlineImage: function(image) { + endInlineImage: function canvasGraphicsEndInlineImage(image) { this.paintImageXObject(null, image, true); }, // XObjects - paintXObject: function(obj) { + paintXObject: function canvasGraphicsPaintXObject(obj) { var xobj = this.xobjs.get(obj.name); if (!xobj) return; @@ -5222,7 +5239,7 @@ var CanvasGraphics = (function() { } }, - paintFormXObject: function(ref, stream) { + paintFormXObject: function canvasGraphicsPaintFormXObject(ref, stream) { this.save(); var matrix = stream.dict.get('Matrix'); @@ -5241,7 +5258,8 @@ var CanvasGraphics = (function() { this.restore(); }, - paintImageXObject: function(ref, image, inline) { + paintImageXObject: function canvasGraphicsPaintImageXObject(ref, image, + inline) { this.save(); var ctx = this.ctx; @@ -5288,34 +5306,35 @@ var CanvasGraphics = (function() { // Marked content - markPoint: function(tag) { + markPoint: function canvasGraphicsMarkPoint(tag) { TODO('Marked content'); }, - markPointProps: function(tag, properties) { + markPointProps: function canvasGraphicsMarkPointProps(tag, properties) { TODO('Marked content'); }, - beginMarkedContent: function(tag) { + beginMarkedContent: function canvasGraphicsBeginMarkedContent(tag) { TODO('Marked content'); }, - beginMarkedContentProps: function(tag, properties) { + beginMarkedContentProps: + function canvasGraphicsBeginMarkedContentProps(tag, properties) { TODO('Marked content'); }, - endMarkedContent: function() { + endMarkedContent: function canvasGraphicsEndMarkedContent() { TODO('Marked content'); }, // Compatibility - beginCompat: function() { + beginCompat: function canvasGraphicsBeginCompat() { TODO('ignore undefined operators (should we do that anyway?)'); }, - endCompat: function() { + endCompat: function canvasGraphicsEndCompat() { TODO('stop ignoring undefined operators'); }, // Helper functions - consumePath: function() { + consumePath: function canvasGraphicsConsumePath() { if (this.pendingClip) { var savedFillRule = null; if (this.pendingClip == EO_CLIP) @@ -5332,12 +5351,12 @@ var CanvasGraphics = (function() { // We generally keep the canvas context set for // nonzero-winding, and just set evenodd for the operations // that need them. - setEOFillRule: function() { + setEOFillRule: function canvasGraphicsSetEOFillRule() { var savedFillRule = this.ctx.mozFillRule; this.ctx.mozFillRule = 'evenodd'; return savedFillRule; }, - restoreFillRule: function(rule) { + restoreFillRule: function canvasGraphicsRestoreFillRule(rule) { this.ctx.mozFillRule = rule; } }; @@ -5345,7 +5364,7 @@ var CanvasGraphics = (function() { return constructor; })(); -var Util = (function() { +var Util = (function utilUtil() { function constructor() {} constructor.makeCssRgb = function makergb(r, g, b) { var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0; @@ -5365,7 +5384,7 @@ var Util = (function() { return constructor; })(); -var ColorSpace = (function() { +var ColorSpace = (function colorSpaceColorSpace() { // Constructor should define this.numComps, this.defaultColor, this.name function constructor() { error('should not call ColorSpace constructor'); @@ -5472,7 +5491,7 @@ var ColorSpace = (function() { return constructor; })(); -var SeparationCS = (function() { +var SeparationCS = (function separationCS() { function constructor(base, tintFn) { this.name = 'Separation'; this.numComps = 1; @@ -5511,7 +5530,7 @@ var SeparationCS = (function() { return constructor; })(); -var PatternCS = (function() { +var PatternCS = (function patternCS() { function constructor(baseCS) { this.name = 'Pattern'; this.base = baseCS; @@ -5521,7 +5540,7 @@ var PatternCS = (function() { return constructor; })(); -var IndexedCS = (function() { +var IndexedCS = (function indexedCS() { function constructor(base, highVal, lookup) { this.name = 'Indexed'; this.numComps = 1; @@ -5578,7 +5597,7 @@ var IndexedCS = (function() { return constructor; })(); -var DeviceGrayCS = (function() { +var DeviceGrayCS = (function deviceGrayCS() { function constructor() { this.name = 'DeviceGray'; this.numComps = 1; @@ -5606,7 +5625,7 @@ var DeviceGrayCS = (function() { return constructor; })(); -var DeviceRgbCS = (function() { +var DeviceRgbCS = (function deviceRgbCS() { function constructor(bits) { this.name = 'DeviceRGB'; this.numComps = 3; @@ -5630,7 +5649,7 @@ var DeviceRgbCS = (function() { return constructor; })(); -var DeviceCmykCS = (function() { +var DeviceCmykCS = (function deviceCmykCS() { function constructor() { this.name = 'DeviceCMYK'; this.numComps = 4; @@ -5714,7 +5733,7 @@ var DeviceCmykCS = (function() { return constructor; })(); -var Pattern = (function() { +var Pattern = (function patternPattern() { // Constructor should define this.getPattern function constructor() { error('should not call Pattern constructor'); @@ -5786,7 +5805,7 @@ var Pattern = (function() { return constructor; })(); -var DummyShading = (function() { +var DummyShading = (function dummyShading() { function constructor() { this.type = 'Pattern'; } @@ -5800,7 +5819,7 @@ var DummyShading = (function() { // Radial and axial shading have very similar implementations // If needed, the implementations can be broken into two classes -var RadialAxialShading = (function() { +var RadialAxialShading = (function radialAxialShading() { function constructor(dict, matrix, xref, res, ctx) { this.matrix = matrix; this.coordsArr = dict.get('Coords'); @@ -5857,7 +5876,7 @@ var RadialAxialShading = (function() { } constructor.prototype = { - getPattern: function() { + getPattern: function radialAxialShadingGetPattern() { var coordsArr = this.coordsArr; var type = this.shadingType; var p0, p1, r0, r1; @@ -5909,7 +5928,7 @@ var RadialAxialShading = (function() { return constructor; })(); -var TilingPattern = (function() { +var TilingPattern = (function tilingPattern() { var PAINT_TYPE_COLORED = 1, PAINT_TYPE_UNCOLORED = 2; function constructor(pattern, code, dict, color, xref, ctx) { @@ -6017,7 +6036,7 @@ var TilingPattern = (function() { })(); -var PDFImage = (function() { +var PDFImage = (function pDFImage() { function constructor(xref, res, image, inline) { this.image = image; if (image.getParams) { @@ -6228,7 +6247,7 @@ var PDFImage = (function() { return constructor; })(); -var PDFFunction = (function() { +var PDFFunction = (function pDFFunction() { function constructor(xref, fn) { var dict = fn.dict; if (!dict) @@ -6249,7 +6268,7 @@ var PDFFunction = (function() { } constructor.prototype = { - constructSampled: function(str, dict) { + constructSampled: function pDFFunctionConstructSampled(str, dict) { var domain = dict.get('Domain'); var range = dict.get('Range'); @@ -6285,8 +6304,8 @@ var PDFFunction = (function() { var samples = this.getSampleArray(size, outputSize, bps, str); - this.func = function(args) { - var clip = function(v, min, max) { + this.func = function pDFFunctionFunc(args) { + var clip = function pDFFunctionClip(v, min, max) { if (v > max) v = max; else if (v < min) @@ -6344,7 +6363,8 @@ var PDFFunction = (function() { return output; }; }, - getSampleArray: function(size, outputSize, bps, str) { + getSampleArray: function pDFFunctionGetSampleArray(size, outputSize, bps, + str) { var length = 1; for (var i = 0; i < size.length; i++) length *= size[i]; @@ -6369,7 +6389,8 @@ var PDFFunction = (function() { } return array; }, - constructInterpolated: function(str, dict) { + constructInterpolated: function pDFFunctionConstructInterpolated(str, + dict) { var c0 = dict.get('C0') || [0]; var c1 = dict.get('C1') || [1]; var n = dict.get('N'); @@ -6382,7 +6403,7 @@ var PDFFunction = (function() { for (var i = 0; i < length; ++i) diff.push(c1[i] - c0[i]); - this.func = function(args) { + this.func = function pDFFunctionConstructInterpolatedFunc(args) { var x = args[0]; var out = []; From 7dc887ace3643c72b926eff91cec75e6e04f9c83 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Wed, 21 Sep 2011 17:28:48 -0500 Subject: [PATCH 15/39] Fixing lint errors introduced by #505 --- web/viewer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/viewer.js b/web/viewer.js index 72b540664..19f088c59 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -110,15 +110,15 @@ var PDFView = { var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.mozResponseType = xhr.responseType = 'arraybuffer'; - xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; + xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200; xhr.onprogress = PDFView.progressLevel; xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === xhr.expected) { var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || xhr.responseArrayBuffer || xhr.response); - - document.getElementById('loading').style.display = "none"; + + document.getElementById('loading').style.display = 'none'; PDFView.load(data, scale); } }; From b7796f123afef8f72fa68443640c4b6fadf98e34 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 22 Sep 2011 00:32:36 +0200 Subject: [PATCH 16/39] Support CropBox attribute --- pdf.js | 25 +++++++++++++++++++++++++ web/viewer.css | 10 ++++++---- web/viewer.js | 45 ++++++++++++++++++++++++++++++--------------- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/pdf.js b/pdf.js index 224becdf1..001257af0 100644 --- a/pdf.js +++ b/pdf.js @@ -3319,6 +3319,31 @@ var Page = (function() { return shadow(this, 'mediaBox', ((IsArray(obj) && obj.length == 4) ? obj : null)); }, + get view() { + var obj = this.inheritPageProp('CropBox'); + var view = { + x: 0, + y: 0, + width: this.width, + height: this.height + }; + if (IsArray(obj) && obj.length == 4) { + var rotate = this.rotate; + if (rotate == 0 || rotate == 180) { + view.x = obj[0]; + view.y = obj[1]; + view.width = obj[2] - view.x; + view.height = obj[3] - view.y; + } else { + view.x = obj[1]; + view.y = obj[0]; + view.width = obj[3] - view.x; + view.height = obj[2] - view.y; + } + } + + return shadow(this, 'cropBox', view); + }, get annotations() { return shadow(this, 'annotations', this.inheritPageProp('Annots')); }, diff --git a/web/viewer.css b/web/viewer.css index cda191a76..e72bdc286 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -119,6 +119,7 @@ span#info { margin-right:auto; line-height: 134px; text-align: center; + overflow: hidden; } .thumbnail:not([data-loaded]) { @@ -195,16 +196,17 @@ span#info { canvas { margin: auto; display: block; - box-shadow: 0px 4px 10px #000; - -moz-box-shadow: 0px 4px 10px #000; - -webkit-box-shadow: 0px 4px 10px #000; } .page { width: 816px; height: 1056px; margin: 10px auto; - position:relative; + position: relative; + overflow: hidden; + box-shadow: 0px 4px 10px #000; + -moz-box-shadow: 0px 4px 10px #000; + -webkit-box-shadow: 0px 4px 10px #000; } .page > a { diff --git a/web/viewer.js b/web/viewer.js index 72b540664..f4f28b8ab 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -58,9 +58,9 @@ var PDFView = { var currentPage = this.pages[this.page - 1]; var pageWidthScale = (window.innerWidth - kScrollbarPadding) / - currentPage.width / kCssUnits; + currentPage.width / kCssUnits; var pageHeightScale = (window.innerHeight - kScrollbarPadding) / - currentPage.height / kCssUnits; + currentPage.height / kCssUnits; if ('page-width' == value) this.setScale(pageWidthScale, resetAutoSettings); if ('page-height' == value) @@ -170,7 +170,7 @@ var PDFView = { var page = pdf.getPage(i); pages.push(new PageView(container, page, i, page.width, page.height, page.stats, this.navigateTo.bind(this))); - thumbnails.push(new ThumbnailView(sidebar, pages[i - 1], + thumbnails.push(new ThumbnailView(sidebar, page, i, page.width / page.height)); var pageRef = page.ref; pagesRefMap[pageRef.num + ' ' + pageRef.gen + ' R'] = i; @@ -237,13 +237,17 @@ var PDFView = { } }; -var PageView = function(container, content, id, width, height, +var PageView = function(container, content, id, pageWidth, pageHeight, stats, navigateTo) { - this.width = width; - this.height = height; this.id = id; this.content = content; + var view = this.content.view; + this.x = view.x; + this.y = view.y; + this.width = view.width; + this.height = view.height; + var anchor = document.createElement('a'); anchor.name = '' + this.id; @@ -272,11 +276,12 @@ var PageView = function(container, content, id, width, height, return false; }; } + var links = content.getLinks(); for (var i = 0; i < links.length; i++) { var link = document.createElement('a'); - link.style.left = Math.floor(links[i].x * scale) + 'px'; - link.style.top = Math.floor(links[i].y * scale) + 'px'; + link.style.left = (Math.floor(links[i].x - this.x) * scale) + 'px'; + link.style.top = (Math.floor(links[i].y - this.y) * scale) + 'px'; link.style.width = Math.ceil(links[i].width * scale) + 'px'; link.style.height = Math.ceil(links[i].height * scale) + 'px'; link.href = links[i].url || ''; @@ -364,8 +369,9 @@ var PageView = function(container, content, id, width, height, canvas.id = 'page' + this.id; canvas.mozOpaque = true; - canvas.width = this.width * this.scale; - canvas.height = this.height * this.scale; + var scale = this.scale; + canvas.width = pageWidth * scale; + canvas.height = pageHeight * scale; div.appendChild(canvas); var ctx = canvas.getContext('2d'); @@ -373,6 +379,7 @@ var PageView = function(container, content, id, width, height, ctx.fillStyle = 'rgb(255, 255, 255)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.restore(); + ctx.translate(-this.x * scale, -this.y * scale); stats.begin = Date.now(); this.content.startRendering(ctx, this.updateStats); @@ -391,12 +398,12 @@ var PageView = function(container, content, id, width, height, }; }; -var ThumbnailView = function(container, page, pageRatio) { +var ThumbnailView = function(container, page, id, pageRatio) { var anchor = document.createElement('a'); - anchor.href = '#' + page.id; + anchor.href = '#' + id; var div = document.createElement('div'); - div.id = 'thumbnailContainer' + page.id; + div.id = 'thumbnailContainer' + id; div.className = 'thumbnail'; anchor.appendChild(div); @@ -407,7 +414,7 @@ var ThumbnailView = function(container, page, pageRatio) { return; var canvas = document.createElement('canvas'); - canvas.id = 'thumbnail' + page.id; + canvas.id = 'thumbnail' + id; canvas.mozOpaque = true; var maxThumbSize = 134; @@ -425,7 +432,15 @@ var ThumbnailView = function(container, page, pageRatio) { ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.restore(); - page.content.startRendering(ctx, function() { }); + var view = page.view; + var scaleX = (canvas.width / page.width); + var scaleY = (canvas.height / page.height); + ctx.translate(-view.x * scaleX, -view.y * scaleY); + div.style.width = (view.width * scaleX) + 'px'; + div.style.height = (view.height * scaleY) + 'px'; + div.style.lineHeight = (view.height * scaleY) + 'px'; + + page.startRendering(ctx, function() { }); }; }; From d8905b524d2ff3d7590b56ed990e6602de526793 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 22 Sep 2011 00:44:51 +0200 Subject: [PATCH 17/39] Fix a lint error --- web/viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/viewer.js b/web/viewer.js index f4f28b8ab..fb3af2ad4 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -281,7 +281,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight, for (var i = 0; i < links.length; i++) { var link = document.createElement('a'); link.style.left = (Math.floor(links[i].x - this.x) * scale) + 'px'; - link.style.top = (Math.floor(links[i].y - this.y) * scale) + 'px'; + link.style.top = (Math.floor(links[i].y - this.y) * scale) + 'px'; link.style.width = Math.ceil(links[i].width * scale) + 'px'; link.style.height = Math.ceil(links[i].height * scale) + 'px'; link.href = links[i].url || ''; From 41ebb55d75a949f7d4e466e3876c8ae3db964cd4 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 22 Sep 2011 01:22:34 +0200 Subject: [PATCH 18/39] Fix tests failures --- fonts.js | 4 ++-- test/test_slave.html | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fonts.js b/fonts.js index 7cd27f8b0..60ad67a52 100644 --- a/fonts.js +++ b/fonts.js @@ -2571,9 +2571,9 @@ var Type2CFF = (function() { if (pos == 0) { return ISOAdobeCharset; } else if (pos == 1) { - return CFFExpertCharset; + return ExpertCharset; } else if (pos == 2) { - return CFFExpertSubsetCharset; + return ExpertSubsetCharset; } var bytes = this.bytes; diff --git a/test/test_slave.html b/test/test_slave.html index 91b8a6850..b46e29d6b 100644 --- a/test/test_slave.html +++ b/test/test_slave.html @@ -7,6 +7,7 @@ + From 2248690d110b48fd3d30ed235b405020351d27e3 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Wed, 21 Sep 2011 19:56:09 -0500 Subject: [PATCH 19/39] Guess default width for FileFont3 using BaseFont --- pdf.js | 82 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/pdf.js b/pdf.js index 9a0b0977a..7e56c309f 100644 --- a/pdf.js +++ b/pdf.js @@ -4483,6 +4483,32 @@ var PartialEvaluator = (function() { return glyphs; }, + getBaseFontMetrics: function(baseFontName) { + var map = {}; + if (/^Symbol(-?(Bold|Italic))*$/.test(baseFontName)) { + // special case for symbols + var encoding = Encodings.symbolsEncoding; + for (var i = 0, n = encoding.length, j; i < n; i++) { + if (!(j = encoding[i])) + continue; + map[i] = GlyphsUnicode[j] || 0; + } + } + + var defaultWidth = 0; + var widths = Metrics[stdFontMap[baseFontName] || baseFontName]; + if (IsNum(widths)) { + defaultWidth = widths; + widths = null; + } + + return { + defaultWidth: defaultWidth, + widths: widths || [], + map: map + }; + }, + translateFont: function(dict, xref, resources) { var baseDict = dict; var type = dict.get('Subtype'); @@ -4518,30 +4544,15 @@ var PartialEvaluator = (function() { return null; // Using base font name as a font name. - baseFontName = baseFontName.name; - var map = {}; - if (/^Symbol(-?(Bold|Italic))*$/.test(baseFontName)) { - // special case for symbols - var encoding = Encodings.symbolsEncoding; - for (var i = 0, n = encoding.length, j; i < n; i++) { - if (!(j = encoding[i])) - continue; - map[i] = GlyphsUnicode[j] || 0; - } - } + baseFontName = baseFontName.name.replace(/,/g, '_'); + var metrics = this.getBaseFontMetrics(baseFontName); - var defaultWidth = 0; - var widths = Metrics[stdFontMap[baseFontName] || baseFontName]; - if (IsNum(widths)) { - defaultWidth = widths; - widths = null; - } var properties = { type: type.name, - encoding: map, + encoding: metrics.map, differences: [], - widths: widths || {}, - defaultWidth: defaultWidth, + widths: metrics.widths, + defaultWidth: metrics.defaultWidth, firstChar: 0, lastChar: 256 }; @@ -4561,7 +4572,25 @@ var PartialEvaluator = (function() { // a variant. var firstChar = xref.fetchIfRef(dict.get('FirstChar')) || 0; var lastChar = xref.fetchIfRef(dict.get('LastChar')) || 256; - var widths = xref.fetchIfRef(dict.get('Widths')) || []; + var defaultWidth = 0; + var glyphWidths = {}; + var encoding = {}; + var widths = xref.fetchIfRef(dict.get('Widths')); + if (widths) { + for (var i = 0, j = firstChar; i < widths.length; i++, j++) + glyphWidths[j] = widths[i]; + defaultWidth = parseFloat(descriptor.get('MissingWidth')) || 0; + } else { + // Trying get the BaseFont metrics (see comment above). + var baseFontName = dict.get('BaseFont'); + if (IsName(baseFontName)) { + var metrics = this.getBaseFontMetrics(baseFontName.name); + + glyphWidths = metrics.widths; + defaultWidth = metrics.defaultWidth; + encoding = metrics.map; + } + } var fontName = xref.fetchIfRef(descriptor.get('FontName')); assertWellFormed(IsName(fontName), 'invalid font name'); @@ -4600,17 +4629,12 @@ var PartialEvaluator = (function() { descent: descriptor.get('Descent'), xHeight: descriptor.get('XHeight'), capHeight: descriptor.get('CapHeight'), - defaultWidth: parseFloat(descriptor.get('MissingWidth')) || 0, + defaultWidth: defaultWidth, flags: descriptor.get('Flags'), italicAngle: descriptor.get('ItalicAngle'), differences: [], - widths: (function() { - var glyphWidths = {}; - for (var i = 0; i < widths.length; i++) - glyphWidths[firstChar++] = widths[i]; - return glyphWidths; - })(), - encoding: {} + widths: glyphWidths, + encoding: encoding }; properties.glyphs = this.extractEncoding(dict, xref, properties); From fc5ae0f87548cb2d137519c3b78d23b9248a5392 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Wed, 21 Sep 2011 21:53:36 -0500 Subject: [PATCH 20/39] Fixing getBaseFontMetricsAndMap function name --- pdf.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pdf.js b/pdf.js index f6f4a3b52..1a5bf4854 100644 --- a/pdf.js +++ b/pdf.js @@ -4490,9 +4490,9 @@ var PartialEvaluator = (function partialEvaluator() { return glyphs; }, - getBaseFontMetrics: function(baseFontName) { + getBaseFontMetricsAndMap: function getBaseFontMetricsAndMap(name) { var map = {}; - if (/^Symbol(-?(Bold|Italic))*$/.test(baseFontName)) { + if (/^Symbol(-?(Bold|Italic))*$/.test(name)) { // special case for symbols var encoding = Encodings.symbolsEncoding; for (var i = 0, n = encoding.length, j; i < n; i++) { @@ -4503,7 +4503,7 @@ var PartialEvaluator = (function partialEvaluator() { } var defaultWidth = 0; - var widths = Metrics[stdFontMap[baseFontName] || baseFontName]; + var widths = Metrics[stdFontMap[name] || name]; if (IsNum(widths)) { defaultWidth = widths; widths = null; @@ -4553,14 +4553,14 @@ var PartialEvaluator = (function partialEvaluator() { // Using base font name as a font name. baseFontName = baseFontName.name.replace(/,/g, '_'); - var metrics = this.getBaseFontMetrics(baseFontName); + var metricsAndMap = this.getBaseFontMetricsAndMap(baseFontName); var properties = { type: type.name, - encoding: metrics.map, + encoding: metricsAndMap.map, differences: [], - widths: metrics.widths, - defaultWidth: metrics.defaultWidth, + widths: metricsAndMap.widths, + defaultWidth: metricsAndMap.defaultWidth, firstChar: 0, lastChar: 256 }; @@ -4592,11 +4592,11 @@ var PartialEvaluator = (function partialEvaluator() { // Trying get the BaseFont metrics (see comment above). var baseFontName = dict.get('BaseFont'); if (IsName(baseFontName)) { - var metrics = this.getBaseFontMetrics(baseFontName.name); + var metricsAndMap = this.getBaseFontMetricsAndMap(baseFontName.name); - glyphWidths = metrics.widths; - defaultWidth = metrics.defaultWidth; - encoding = metrics.map; + glyphWidths = metricsAndMap.widths; + defaultWidth = metricsAndMap.defaultWidth; + encoding = metricsAndMap.map; } } From da6acb200ab34771ed9629c0a67fba0fd9a576b3 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Thu, 22 Sep 2011 13:39:28 +0200 Subject: [PATCH 21/39] Fix tests failure by cloning the GlyphsUnicode object --- fonts.js | 17 +++++++++-------- pdf.js | 9 +++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/fonts.js b/fonts.js index 60ad67a52..e5cce0b4f 100644 --- a/fonts.js +++ b/fonts.js @@ -447,13 +447,14 @@ var Font = (function Font() { } var data; - switch (properties.type) { + var type = properties.type; + switch (type) { case 'Type1': case 'CIDFontType0': this.mimetype = 'font/opentype'; var subtype = properties.subtype; - var cff = (subtype == 'Type1C' || properties.type == 'CIDFontType0') ? + var cff = (subtype == 'Type1C' || subtype == 'CIDFontType0C') ? new Type2CFF(file, properties) : new CFF(name, file, properties); // Wrap the CFF data inside an OTF font file @@ -475,7 +476,7 @@ var Font = (function Font() { } this.data = data; - this.type = properties.type; + this.type = type; this.textMatrix = properties.textMatrix; this.defaultWidth = properties.defaultWidth; this.loadedName = getUniqueName(); @@ -2522,8 +2523,8 @@ var Type2CFF = (function() { if (pos == 0 || pos == 1) { var gid = 1; - var baseEncoding = - pos ? Encodings.ExpertEncoding : Encodings.StandardEncoding; + var baseEncoding = pos ? Encodings.ExpertEncoding.slice() : + Encodings.StandardEncoding.slice(); for (var i = 0; i < charset.length; i++) { var index = baseEncoding.indexOf(charset[i]); if (index != -1) @@ -2569,11 +2570,11 @@ var Type2CFF = (function() { parseCharsets: function cff_parsecharsets(pos, length, strings) { if (pos == 0) { - return ISOAdobeCharset; + return ISOAdobeCharset.slice(); } else if (pos == 1) { - return ExpertCharset; + return ExpertCharset.slice(); } else if (pos == 2) { - return ExpertSubsetCharset; + return ExpertSubsetCharset.slice(); } var bytes = this.bytes; diff --git a/pdf.js b/pdf.js index 1a5bf4854..1b80424d6 100644 --- a/pdf.js +++ b/pdf.js @@ -4280,8 +4280,9 @@ var PartialEvaluator = (function partialEvaluator() { properties.widths = glyphsWidths; var cidToGidMap = dict.get('CIDToGIDMap'); - if (!cidToGidMap || !IsRef(cidToGidMap)) - return GlyphsUnicode; + if (!cidToGidMap || !IsRef(cidToGidMap)) { + return Object.create(GlyphsUnicode); + } // Extract the encoding from the CIDToGIDMap var glyphsStream = xref.fetchIfRef(cidToGidMap); @@ -4318,7 +4319,7 @@ var PartialEvaluator = (function partialEvaluator() { '9.7.5.3'); } } - return GlyphsUnicode; + return Object.create(GlyphsUnicode); } var differences = properties.differences; @@ -4494,7 +4495,7 @@ var PartialEvaluator = (function partialEvaluator() { var map = {}; if (/^Symbol(-?(Bold|Italic))*$/.test(name)) { // special case for symbols - var encoding = Encodings.symbolsEncoding; + var encoding = Encodings.symbolsEncoding.slice(); for (var i = 0, n = encoding.length, j; i < n; i++) { if (!(j = encoding[i])) continue; From 5c772329d8e5f558f1af9a8bca5f3f0945b8edca Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Thu, 22 Sep 2011 23:01:16 +0300 Subject: [PATCH 22/39] Make showText and showSpacedText slightly faster. --- pdf.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pdf.js b/pdf.js index 1b80424d6..67b21b01f 100644 --- a/pdf.js +++ b/pdf.js @@ -5033,7 +5033,8 @@ var CanvasGraphics = (function canvasGraphics() { ctx.scale(1 / textHScale, 1); var width = 0; - for (var i = 0; i < glyphs.length; i++) { + var glyphsLength = glyphs.length; + for (var i = 0; i < glyphsLength; ++i) { var glyph = glyphs[i]; if (glyph === null) { // word break @@ -5042,34 +5043,35 @@ var CanvasGraphics = (function canvasGraphics() { } var unicode = glyph.unicode; - var char = unicode >= 0x10000 ? + var char = (unicode >= 0x10000) ? String.fromCharCode(0xD800 | ((unicode - 0x10000) >> 10), 0xDC00 | (unicode & 0x3FF)) : String.fromCharCode(unicode); - var charWidth = glyph.width * fontSize * 0.001; - charWidth += charSpacing; - ctx.fillText(char, width, 0); - width += charWidth; + width += glyph.width * fontSize * 0.001 + charSpacing; } current.x += width; this.ctx.restore(); }, showSpacedText: function canvasGraphicsShowSpacedText(arr) { - for (var i = 0; i < arr.length; ++i) { + var ctx = this.ctx; + var current = this.current; + var fontSize = current.fontSize; + var textHScale = current.textHScale; + var arrLength = arr.length; + for (var i = 0; i < arrLength; ++i) { var e = arr[i]; if (IsNum(e)) { - if (this.ctx.$addCurrentX) { - this.ctx.$addCurrentX(-e * 0.001 * this.current.fontSize); + if (ctx.$addCurrentX) { + ctx.$addCurrentX(-e * 0.001 * fontSize); } else { - this.current.x -= e * 0.001 * this.current.fontSize * - this.current.textHScale; + current.x -= e * 0.001 * fontSize * textHScale; } } else if (IsString(e)) { this.showText(e); } else { - malformed('TJ array element ' + e + " isn't string or num"); + malformed('TJ array element ' + e + ' is not string or num'); } } }, From 8072052fb19d0190e8ba149fc6749e8dc3a463ea Mon Sep 17 00:00:00 2001 From: = <=> Date: Thu, 22 Sep 2011 13:17:28 -0700 Subject: [PATCH 23/39] Handle references for color space names that are defined in a dictionary --- pdf.js | 2 +- test/pdfs/hudsonsurvey.pdf.link | 1 + test/test_manifest.json | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test/pdfs/hudsonsurvey.pdf.link diff --git a/pdf.js b/pdf.js index 1b80424d6..8a7c645ce 100644 --- a/pdf.js +++ b/pdf.js @@ -5431,7 +5431,7 @@ var ColorSpace = (function colorSpaceColorSpace() { constructor.parse = function colorspace_parse(cs, xref, res) { if (IsName(cs)) { - var colorSpaces = res.get('ColorSpace'); + var colorSpaces = xref.fetchIfRef(res.get('ColorSpace')); if (IsDict(colorSpaces)) { var refcs = colorSpaces.get(cs.name); if (refcs) diff --git a/test/pdfs/hudsonsurvey.pdf.link b/test/pdfs/hudsonsurvey.pdf.link new file mode 100644 index 000000000..ab3b730db --- /dev/null +++ b/test/pdfs/hudsonsurvey.pdf.link @@ -0,0 +1 @@ +https://issues.apache.org/jira/secure/attachment/12421789/survey.pdf \ No newline at end of file diff --git a/test/test_manifest.json b/test/test_manifest.json index edf13b7c5..231857fa8 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -145,5 +145,11 @@ "link": true, "rounds": 1, "type": "load" + }, + { "id": "hudsonsurvey", + "file": "pdfs/hudsonsurvey.pdf", + "link": true, + "rounds": 1, + "type": "load" } ] From 107576d634ae39d8ee60ce9dd25e28a9c6112bc0 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Thu, 22 Sep 2011 18:04:50 -0500 Subject: [PATCH 24/39] Removing introduced by the test run DOM elements --- test/driver.js | 13 +++++++++++++ test/test_slave.html | 1 + 2 files changed, 14 insertions(+) diff --git a/test/driver.js b/test/driver.js index 7d6c54509..db6c9b501 100644 --- a/test/driver.js +++ b/test/driver.js @@ -50,7 +50,20 @@ function load() { r.send(null); } +function cleanup() { + var styleSheet = document.styleSheets[0]; + if (styleSheet) { + while (styleSheet.cssRules.length > 0) + styleSheet.deleteRule(0); + } + var guard = document.getElementById('content-end'); + while (document.body.lastChild != guard) + document.body.removeChild(document.body.lastChild); +} + function nextTask() { + cleanup(); + if (currentTaskIdx == manifest.length) { return done(); } diff --git a/test/test_slave.html b/test/test_slave.html index b46e29d6b..57d8d7a83 100644 --- a/test/test_slave.html +++ b/test/test_slave.html @@ -14,6 +14,7 @@

   

Inflight requests:

+
From 7fd6283d6f2648e45363a50215853ec357466243 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Thu, 22 Sep 2011 18:29:43 -0500 Subject: [PATCH 25/39] Fixing hyperlinks (regr. #509) --- web/viewer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/viewer.js b/web/viewer.js index 9d89c8801..89d83fe6b 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -280,8 +280,8 @@ var PageView = function(container, content, id, pageWidth, pageHeight, var links = content.getLinks(); for (var i = 0; i < links.length; i++) { var link = document.createElement('a'); - link.style.left = (Math.floor(links[i].x - this.x) * scale) + 'px'; - link.style.top = (Math.floor(links[i].y - this.y) * scale) + 'px'; + link.style.left = (Math.floor(links[i].x - view.x) * scale) + 'px'; + link.style.top = (Math.floor(links[i].y - view.y) * scale) + 'px'; link.style.width = Math.ceil(links[i].width * scale) + 'px'; link.style.height = Math.ceil(links[i].height * scale) + 'px'; link.href = links[i].url || ''; From f3e4cf20cc6d4173ec45669d26f05cf929da10a7 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Thu, 22 Sep 2011 20:18:43 -0500 Subject: [PATCH 26/39] intermediate variable for document.body --- test/driver.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/driver.js b/test/driver.js index db6c9b501..3e3097107 100644 --- a/test/driver.js +++ b/test/driver.js @@ -57,8 +57,9 @@ function cleanup() { styleSheet.deleteRule(0); } var guard = document.getElementById('content-end'); - while (document.body.lastChild != guard) - document.body.removeChild(document.body.lastChild); + var body = document.body; + while (body.lastChild != guard) + body.removeChild(body.lastChild); } function nextTask() { From ba74e56c35b7c74d7e65405dfcae082664962c1b Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Fri, 23 Sep 2011 06:58:54 -0500 Subject: [PATCH 27/39] Using !== for objects comparison --- test/driver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/driver.js b/test/driver.js index 3e3097107..e7c125347 100644 --- a/test/driver.js +++ b/test/driver.js @@ -58,7 +58,7 @@ function cleanup() { } var guard = document.getElementById('content-end'); var body = document.body; - while (body.lastChild != guard) + while (body.lastChild !== guard) body.removeChild(body.lastChild); } From 2d03f93fedd5c1a6ea98954d2451375b3683c933 Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Fri, 23 Sep 2011 20:25:24 +0300 Subject: [PATCH 28/39] Name anonymous functions for debugging purposes. It also makes profiling more convenient. --- test/driver.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/test/driver.js b/test/driver.js index 7d6c54509..4751910b2 100644 --- a/test/driver.js +++ b/test/driver.js @@ -39,7 +39,7 @@ function load() { var r = new XMLHttpRequest(); r.open('GET', manifestFile, false); - r.onreadystatechange = function(e) { + r.onreadystatechange = function loadOnreadystatechange(e) { if (r.readyState == 4) { log('done\n'); manifest = JSON.parse(r.responseText); @@ -62,7 +62,7 @@ function nextTask() { var r = new XMLHttpRequest(); r.open('GET', task.file); r.mozResponseType = r.responseType = 'arraybuffer'; - r.onreadystatechange = function() { + r.onreadystatechange = function nextTaskOnreadystatechange() { var failure; if (r.readyState == 4) { var data = r.mozResponseArrayBuffer || r.mozResponse || @@ -85,11 +85,15 @@ function isLastPage(task) { return (task.pageNum > task.pdfDoc.numPages); } +function canvasToDataURL() { + return canvas.toDataURL('image/png'); +} + function nextPage(task, loadError) { var failure = loadError || ''; if (!task.pdfDoc) { - sendTaskResult(canvas.toDataURL('image/png'), task, failure); + sendTaskResult(canvasToDataURL(), task, failure); log('done' + (failure ? ' (failed !: ' + failure + ')' : '') + '\n'); ++currentTaskIdx; nextTask(); @@ -126,7 +130,7 @@ function nextPage(task, loadError) { page.startRendering( ctx, - function(e) { + function nextPageStartRendering(e) { snapshotCurrentPage(task, (!failure && e) ? ('render : ' + e) : failure); } @@ -146,13 +150,13 @@ function nextPage(task, loadError) { function snapshotCurrentPage(task, failure) { log('done, snapshotting... '); - sendTaskResult(canvas.toDataURL('image/png'), task, failure); + sendTaskResult(canvasToDataURL(), task, failure); log('done' + (failure ? ' (failed !: ' + failure + ')' : '') + '\n'); // Set up the next request var backoff = (inFlightRequests > 0) ? inFlightRequests * 10 : 0; setTimeout( - function() { + function snapshotCurrentPageSetTimeout() { ++task.pageNum; nextPage(task); }, @@ -201,7 +205,7 @@ function sendTaskResult(snapshot, task, failure) { // (The POST URI is ignored atm.) r.open('POST', '/submit_task_results', true); r.setRequestHeader('Content-Type', 'application/json'); - r.onreadystatechange = function(e) { + r.onreadystatechange = function sendTaskResultOnreadystatechange(e) { if (r.readyState == 4) { inFlightRequests--; } From 0d5efbe9fec1a81b1b08ecf1308b4e20299d1c66 Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Fri, 23 Sep 2011 20:44:48 +0300 Subject: [PATCH 29/39] Name anonymous functions for debugging purposes. It also makes profiling more convenient. --- fonts.js | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/fonts.js b/fonts.js index e5cce0b4f..653751083 100644 --- a/fonts.js +++ b/fonts.js @@ -124,7 +124,7 @@ var serifFonts = { var FontLoader = { listeningForFontLoad: false, - bind: function(fonts, callback) { + bind: function fontLoaderBind(fonts, callback) { function checkFontsLoaded() { for (var i = 0; i < objs.length; i++) { var fontObj = objs[i]; @@ -180,7 +180,7 @@ var FontLoader = { // loaded in a subdocument. It's expected that the load of |rules| // has already started in this (outer) document, so that they should // be ordered before the load in the subdocument. - prepareFontLoadEvent: function(rules, names, objs) { + prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names, objs) { /** Hack begin */ // There's no event when a font has finished downloading so the // following code is a dirty hack to 'guess' when a font is @@ -219,7 +219,7 @@ var FontLoader = { if (!this.listeningForFontLoad) { window.addEventListener( 'message', - function(e) { + function fontLoaderMessage(e) { var fontNames = JSON.parse(e.data); for (var i = 0; i < objs.length; ++i) { var font = objs[i]; @@ -247,7 +247,7 @@ var FontLoader = { fontNamesArray += '"' + names[i] + '", '; } src += ' var fontNames=[' + fontNamesArray + '];\n'; - src += ' window.onload = function () {\n'; + src += ' window.onload = function fontLoaderOnload() {\n'; src += ' parent.postMessage(JSON.stringify(fontNames), "*");\n'; src += ' }'; src += ''; @@ -599,7 +599,7 @@ var Font = (function Font() { var length = glyphs.length; for (var n = 0; n < length; ++n) codes.push({ unicode: glyphs[n].unicode, code: n }); - codes.sort(function(a, b) { + codes.sort(function fontGetRangesSort(a, b) { return a.unicode - b.unicode; }); @@ -928,7 +928,7 @@ var Font = (function Font() { } // Check that table are sorted by platformID then encodingID, - records.sort(function(a, b) { + records.sort(function fontReplaceCMapTableSort(a, b) { return ((a.platformID << 16) + a.encodingID) - ((b.platformID << 16) + b.encodingID); }); @@ -1061,11 +1061,11 @@ var Font = (function Font() { var itemSize, itemDecode, itemEncode; if (isGlyphLocationsLong) { itemSize = 4; - itemDecode = function(data, offset) { + itemDecode = function fontItemDecodeLong(data, offset) { return (data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]; }; - itemEncode = function(data, offset, value) { + itemEncode = function fontItemEncodeLong(data, offset, value) { data[offset] = (value >>> 24) & 0xFF; data[offset + 1] = (value >> 16) & 0xFF; data[offset + 2] = (value >> 8) & 0xFF; @@ -1073,10 +1073,10 @@ var Font = (function Font() { }; } else { itemSize = 2; - itemDecode = function(data, offset) { + itemDecode = function fontItemDecode(data, offset) { return (data[offset] << 9) | (data[offset + 1] << 1); }; - itemEncode = function(data, offset, value) { + itemEncode = function fontItemEncode(data, offset, value) { data[offset] = (value >> 9) & 0xFF; data[offset + 1] = (value >> 1) & 0xFF; }; @@ -1323,7 +1323,7 @@ var Font = (function Font() { 'cmap': createCMapTable(charstrings.slice(), font.glyphIds), // Font header - 'head': (function() { + 'head': (function fontFieldsHead() { return stringToArray( '\x00\x01\x00\x00' + // Version number '\x00\x00\x10\x00' + // fontRevision @@ -1345,7 +1345,7 @@ var Font = (function Font() { })(), // Horizontal header - 'hhea': (function() { + 'hhea': (function fontFieldsHhea() { return stringToArray( '\x00\x01\x00\x00' + // Version number string16(properties.ascent) + // Typographic Ascent @@ -1368,7 +1368,7 @@ var Font = (function Font() { })(), // Horizontal metrics - 'hmtx': (function() { + 'hmtx': (function fontFieldsHmtx() { var hmtx = '\x00\x00\x00\x00'; // Fake .notdef for (var i = 0; i < charstrings.length; i++) { hmtx += string16(charstrings[i].width) + string16(0); @@ -1377,7 +1377,7 @@ var Font = (function Font() { })(), // Maximum profile - 'maxp': (function() { + 'maxp': (function fontFieldsMaxp() { return stringToArray( '\x00\x00\x50\x00' + // Version number string16(charstrings.length + 1)); // Num of glyphs @@ -1505,7 +1505,7 @@ var Font = (function Font() { * program. Some of its logic depends on the Type2 charstrings * structure. */ -var Type1Parser = function() { +var Type1Parser = function type1Parser() { /* * Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence * of Plaintext Bytes. The function took a key as a parameter which can be @@ -2033,7 +2033,7 @@ var CFFStrings = [ var type1Parser = new Type1Parser(); -var CFF = function(name, file, properties) { +var CFF = function cFF(name, file, properties) { // Get the data block containing glyphs and subrs informations var headerBlock = file.getBytes(properties.length1); type1Parser.extractFontHeader(headerBlock, properties); @@ -2233,7 +2233,7 @@ CFF.prototype = { 'names': this.createCFFIndexHeader([name]), 'topDict': (function topDict(self) { - return function() { + return function cFFWrapTopDict() { var header = '\x00\x01\x01\x01'; var dict = '\xf8\x1b\x00' + // version @@ -2310,7 +2310,7 @@ CFF.prototype = { 'charstrings': this.createCFFIndexHeader([[0x8B, 0x0E]].concat(glyphs), true), - 'private': (function(self) { + 'private': (function cFFWrapPrivate(self) { var data = '\x8b\x14' + // defaultWidth '\x8b\x15'; // nominalWidth @@ -2363,7 +2363,7 @@ CFF.prototype = { } }; -var Type2CFF = (function() { +var Type2CFF = (function type2CFF() { // TODO: replace parsing code with the Type2Parser in font_utils.js function constructor(file, properties) { var bytes = file.getBytes(); @@ -2503,7 +2503,9 @@ var Type2CFF = (function() { } // sort the array by the unicode value - charstrings.sort(function(a, b) {return a.unicode - b.unicode}); + charstrings.sort(function type2CFFGetCharStringsSort(a, b) { + return a.unicode - b.unicode + }); return charstrings; }, From 5ce5ca03d32272321d07b0a624fb942b90b04d78 Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Fri, 23 Sep 2011 20:54:18 +0300 Subject: [PATCH 30/39] Name anonymous functions for debugging purposes. It also makes profiling more convenient. --- crypto.js | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/crypto.js b/crypto.js index a91f9e41d..42eeeda51 100644 --- a/crypto.js +++ b/crypto.js @@ -3,7 +3,7 @@ 'use strict'; -var ARCFourCipher = (function() { +var ARCFourCipher = (function aRCFourCipher() { function constructor(key) { this.a = 0; this.b = 0; @@ -21,7 +21,7 @@ var ARCFourCipher = (function() { } constructor.prototype = { - encryptBlock: function(data) { + encryptBlock: function aRCFourCipherEncryptBlock(data) { var i, n = data.length, tmp, tmp2; var a = this.a, b = this.b, s = this.s; var output = new Uint8Array(n); @@ -45,7 +45,7 @@ var ARCFourCipher = (function() { return constructor; })(); -var md5 = (function() { +var md5 = (function md5Md5() { var r = new Uint8Array([ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, @@ -129,12 +129,12 @@ var md5 = (function() { return hash; })(); -var NullCipher = (function() { +var NullCipher = (function nullCipher() { function constructor() { } constructor.prototype = { - decryptBlock: function(data) { + decryptBlock: function nullCipherDecryptBlock(data) { return data; } }; @@ -142,7 +142,7 @@ var NullCipher = (function() { return constructor; })(); -var AES128Cipher = (function() { +var AES128Cipher = (function aES128Cipher() { var rcon = new Uint8Array([ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, @@ -372,7 +372,7 @@ var AES128Cipher = (function() { } constructor.prototype = { - decryptBlock: function(data) { + decryptBlock: function aES128CipherDecryptBlock(data) { var i, sourceLength = data.length; var buffer = this.buffer, bufferLength = this.bufferPosition; // waiting for IV values -- they are at the start of the stream @@ -395,19 +395,21 @@ var AES128Cipher = (function() { return constructor; })(); -var CipherTransform = (function() { +var CipherTransform = (function cipherTransform() { function constructor(stringCipherConstructor, streamCipherConstructor) { this.stringCipherConstructor = stringCipherConstructor; this.streamCipherConstructor = streamCipherConstructor; } constructor.prototype = { - createStream: function(stream) { + createStream: function cipherTransformCreateStream(stream) { var cipher = new this.streamCipherConstructor(); - return new DecryptStream(stream, function(data) { - return cipher.decryptBlock(data); - }); + return new DecryptStream(stream, + function cipherTransformDecryptStream(data) { + return cipher.decryptBlock(data); + } + ); }, - decryptString: function(s) { + decryptString: function cipherTransformDecryptString(s) { var cipher = new this.stringCipherConstructor(); var data = stringToBytes(s); data = cipher.decryptBlock(data); @@ -417,7 +419,7 @@ var CipherTransform = (function() { return constructor; })(); -var CipherTransformFactory = (function() { +var CipherTransformFactory = (function cipherTransformFactory() { function prepareKeyData(fileId, password, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata) { var defaultPasswordBytes = new Uint8Array([ @@ -552,18 +554,18 @@ var CipherTransformFactory = (function() { if (cryptFilter != null) cfm = cryptFilter.get('CFM'); if (!cfm || cfm.name == 'None') { - return function() { + return function cipherTransformFactoryBuildCipherConstructorNone() { return new NullCipher(); }; } if ('V2' == cfm.name) { - return function() { + return function cipherTransformFactoryBuildCipherConstructorV2() { return new ARCFourCipher( buildObjectKey(num, gen, key, false)); }; } if ('AESV2' == cfm.name) { - return function() { + return function cipherTransformFactoryBuildCipherConstructorAESV2() { return new AES128Cipher( buildObjectKey(num, gen, key, true)); }; @@ -573,7 +575,8 @@ var CipherTransformFactory = (function() { } constructor.prototype = { - createCipherTransform: function(num, gen) { + createCipherTransform: function buildCipherCreateCipherTransform(num, + gen) { if (this.algorithm == 4) { return new CipherTransform( buildCipherConstructor(this.cf, this.stmf, @@ -583,7 +586,7 @@ var CipherTransformFactory = (function() { } // algorithms 1 and 2 var key = buildObjectKey(num, gen, this.encryptionKey, false); - var cipherConstructor = function() { + var cipherConstructor = function buildCipherCipherConstructor() { return new ARCFourCipher(key); }; return new CipherTransform(cipherConstructor, cipherConstructor); From 481f242b5a3acfb0ac0935a12600839bab3e2d4c Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Fri, 23 Sep 2011 20:56:21 +0300 Subject: [PATCH 31/39] Fix lint warnings. --- fonts.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fonts.js b/fonts.js index 653751083..bc1ad5569 100644 --- a/fonts.js +++ b/fonts.js @@ -180,7 +180,8 @@ var FontLoader = { // loaded in a subdocument. It's expected that the load of |rules| // has already started in this (outer) document, so that they should // be ordered before the load in the subdocument. - prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names, objs) { + prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names, + objs) { /** Hack begin */ // There's no event when a font has finished downloading so the // following code is a dirty hack to 'guess' when a font is @@ -2504,7 +2505,7 @@ var Type2CFF = (function type2CFF() { // sort the array by the unicode value charstrings.sort(function type2CFFGetCharStringsSort(a, b) { - return a.unicode - b.unicode + return a.unicode - b.unicode; }); return charstrings; }, From 335e86359dbb37cc309abeef2409490636628400 Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Fri, 23 Sep 2011 20:58:56 +0300 Subject: [PATCH 32/39] Name anonymous functions for debugging purposes. It also makes profiling more convenient. --- pdf.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pdf.js b/pdf.js index 6c66b84c4..3709afa17 100644 --- a/pdf.js +++ b/pdf.js @@ -6466,7 +6466,7 @@ var PDFFunction = (function pDFFunction() { return out; }; }, - constructStiched: function(fn, dict, xref) { + constructStiched: function pDFFunctionConstructStiched(fn, dict, xref) { var domain = dict.get('Domain'); var range = dict.get('Range'); @@ -6485,8 +6485,8 @@ var PDFFunction = (function pDFFunction() { var bounds = dict.get('Bounds'); var encode = dict.get('Encode'); - this.func = function(args) { - var clip = function(v, min, max) { + this.func = function pDFFunctionConstructStichedFunc(args) { + var clip = function pDFFunctionConstructStichedFuncClip(v, min, max) { if (v > max) v = max; else if (v < min) @@ -6519,9 +6519,9 @@ var PDFFunction = (function pDFFunction() { return fns[i].func([v2]); }; }, - constructPostScript: function() { + constructPostScript: function pDFFunctionConstructPostScript() { TODO('unhandled type of function'); - this.func = function() { + this.func = function pDFFunctionConstructPostScriptFunc() { return [255, 105, 180]; }; } From 630c98052e15053e72884a5f5c45f84a496ec3ac Mon Sep 17 00:00:00 2001 From: = <=> Date: Fri, 23 Sep 2011 14:37:44 -0700 Subject: [PATCH 33/39] Adds support for all the basic graphic state operators --- pdf.js | 74 ++++++++++++++++++++++++++-- test/pdfs/extgstate.pdf | 105 ++++++++++++++++++++++++++++++++++++++++ test/test_manifest.json | 6 +++ 3 files changed, 180 insertions(+), 5 deletions(-) create mode 100644 test/pdfs/extgstate.pdf diff --git a/pdf.js b/pdf.js index 1b80424d6..82a6a9bab 100644 --- a/pdf.js +++ b/pdf.js @@ -4791,7 +4791,65 @@ var CanvasGraphics = (function canvasGraphics() { TODO('set flatness: ' + flatness); }, setGState: function canvasGraphicsSetGState(dictName) { - TODO('set graphics state from dict: ' + dictName); + var extGState = this.xref.fetchIfRef(this.res.get('ExtGState')); + if (IsDict(extGState) && extGState.has(dictName.name)) { + var gsState = this.xref.fetchIfRef(extGState.get(dictName.name)); + var self = this; + gsState.forEach(function(key, value) { + switch (key) { + case 'Type': + break; + case 'LW': + self.setLineWidth(value); + break; + case 'LC': + self.setLineCap(value); + break; + case 'LJ': + self.setLineJoin(value); + break; + case 'ML': + self.setMiterLimit(value); + break; + case 'D': + self.setDash(value[0], value[1]); + break; + case 'RI': + self.setRenderingIntent(value); + break; + case 'FL': + self.setFlatness(value); + break; + case 'Font': + self.setFont(value[0], value[1]); + break; + case 'OP': + case 'op': + case 'OPM': + case 'BG': + case 'BG2': + case 'UCR': + case 'UCR2': + case 'TR': + case 'TR2': + case 'HT': + case 'SM': + case 'SA': + case 'BM': + case 'SMask': + case 'CA': + case 'ca': + case 'AIS': + case 'TK': + TODO('graphic state operator ' + key); + break; + default: + warn('Unknown graphic state operator ' + key); + break; + } + }); + } + }, save: function canvasGraphicsSave() { this.ctx.save(); @@ -4958,11 +5016,17 @@ var CanvasGraphics = (function canvasGraphics() { this.current.leading = -leading; }, setFont: function canvasGraphicsSetFont(fontRef, size) { - var font = this.xref.fetchIfRef(this.res.get('Font')); - if (!IsDict(font)) - return; + var font; + // the tf command uses a name, but graphics state uses a reference + if (IsName(fontRef)) { + font = this.xref.fetchIfRef(this.res.get('Font')); + if (!IsDict(font)) + return; - font = font.get(fontRef.name); + font = font.get(fontRef.name); + } else if (IsRef(fontRef)) { + font = fontRef; + } font = this.xref.fetchIfRef(font); if (!font) error('Referenced font is not found'); diff --git a/test/pdfs/extgstate.pdf b/test/pdfs/extgstate.pdf new file mode 100644 index 000000000..711c45147 --- /dev/null +++ b/test/pdfs/extgstate.pdf @@ -0,0 +1,105 @@ +%PDF-1.4 +%öäüß +1 0 obj +<< +/Type /Catalog +/Version /1.4 +/Pages 2 0 R +>> +endobj +2 0 obj +<< +/Type /Pages +/Kids [3 0 R] +/Count 1 +>> +endobj +3 0 obj +<< +/Type /Page +/MediaBox [0 0 612 792] +/Resources 4 0 R +/Parent 2 0 R +/Contents 5 0 R +>> +endobj +4 0 obj +<< +/ExtGState 6 0 R +/Font 7 0 R +/XObject << +>> +>> +endobj +5 0 obj +<< +/Length 8 0 R +>> +stream +/GS1 gs +/F0 12 Tf +BT +100 700 Td +(I should be courier!) Tj +ET +50 600 m +400 600 l +S + +endstream +endobj +6 0 obj +<< +/GS1 9 0 R +>> +endobj +7 0 obj +<< +/F0 10 0 R +>> +endobj +8 0 obj +82 +endobj +9 0 obj +<< +/Type /ExtGState +/LW 10 +/LC 1 +/LJ 2 +/ML 0.3000000119 +/D [[0.0917000026 183.3300018311] + 0] +/Font [10 0 R 36] +>> +endobj +10 0 obj +<< +/Type /Font +/Subtype /Type1 +/BaseFont /Courier +/Encoding /WinAnsiEncoding +>> +endobj +xref +0 11 +0000000000 65535 f +0000000015 00000 n +0000000078 00000 n +0000000135 00000 n +0000000239 00000 n +0000000304 00000 n +0000000441 00000 n +0000000473 00000 n +0000000505 00000 n +0000000523 00000 n +0000000653 00000 n +trailer +<< +/Root 1 0 R +/ID [ ] +/Size 11 +>> +startxref +749 +%%EOF diff --git a/test/test_manifest.json b/test/test_manifest.json index edf13b7c5..5c1802deb 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -145,5 +145,11 @@ "link": true, "rounds": 1, "type": "load" + }, + { "id": "extgstate", + "file": "pdfs/extgstate.pdf", + "link": false, + "rounds": 1, + "type": "load" } ] From ced260c2ff6cf7bd54aee14d7c54b98b7dee5ace Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Fri, 23 Sep 2011 18:08:23 -0500 Subject: [PATCH 34/39] Reset invalid media box to letter size. --- pdf.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index 6c66b84c4..77ac4a29b 100644 --- a/pdf.js +++ b/pdf.js @@ -3321,8 +3321,10 @@ var Page = (function pagePage() { }, get mediaBox() { var obj = this.inheritPageProp('MediaBox'); - return shadow(this, 'mediaBox', - ((IsArray(obj) && obj.length == 4) ? obj : null)); + // Reset invalid media box to letter size. + if (!IsArray(obj) || obj.length === 4) + obj = [0, 0, 612, 792]; + return shadow(this, 'mediaBox', obj); }, get view() { var obj = this.inheritPageProp('CropBox'); From 2ad3a8bd1c3e237a310239de168709d8143d5d9c Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Fri, 23 Sep 2011 21:29:01 -0500 Subject: [PATCH 35/39] Fix mediaBox check (regr. of #519) --- pdf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 350aeb085..f7bde09f1 100644 --- a/pdf.js +++ b/pdf.js @@ -3322,7 +3322,7 @@ var Page = (function pagePage() { get mediaBox() { var obj = this.inheritPageProp('MediaBox'); // Reset invalid media box to letter size. - if (!IsArray(obj) || obj.length === 4) + if (!IsArray(obj) || obj.length !== 4) obj = [0, 0, 612, 792]; return shadow(this, 'mediaBox', obj); }, From c20b981f068a53f9e39dc926f6600a32771b1dbe Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Sat, 24 Sep 2011 09:14:44 -0500 Subject: [PATCH 36/39] Changing the calculateMD5 function name (ref #523) --- crypto.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto.js b/crypto.js index 42eeeda51..4eb6bb581 100644 --- a/crypto.js +++ b/crypto.js @@ -45,7 +45,7 @@ var ARCFourCipher = (function aRCFourCipher() { return constructor; })(); -var md5 = (function md5Md5() { +var calculateMD5 = (function calculateMD5() { var r = new Uint8Array([ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, @@ -452,11 +452,11 @@ var CipherTransformFactory = (function cipherTransformFactory() { hashData[i++] = 0xFF; hashData[i++] = 0xFF; } - var hash = md5(hashData, 0, i); + var hash = calculateMD5(hashData, 0, i); var keyLengthInBytes = keyLength >> 3; if (revision >= 3) { for (j = 0; j < 50; ++j) { - hash = md5(hash, 0, keyLengthInBytes); + hash = calculateMD5(hash, 0, keyLengthInBytes); } } var encryptionKey = hash.subarray(0, keyLengthInBytes); @@ -469,7 +469,7 @@ var CipherTransformFactory = (function cipherTransformFactory() { for (j = 0, n = fileId.length; j < n; ++j) hashData[i++] = fileId[j]; cipher = new ARCFourCipher(encryptionKey); - var checkData = cipher.encryptBlock(md5(hashData, 0, i)); + var checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i)); n = encryptionKey.length; var derrivedKey = new Uint8Array(n), k; for (j = 1; j <= 19; ++j) { @@ -544,7 +544,7 @@ var CipherTransformFactory = (function cipherTransformFactory() { key[i++] = 0x6C; key[i++] = 0x54; } - var hash = md5(key, 0, i); + var hash = calculateMD5(key, 0, i); return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); } From 7789af2f386661b81d7945c1547fc26e6ecd9db1 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Sun, 25 Sep 2011 11:44:29 +0200 Subject: [PATCH 37/39] Add GettingTheCode section to Readme.md --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index c6cf92ede..cbde3e93b 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,32 @@ For an online demo, visit: This demo provides an interactive interface for displaying and browsing PDFs using the pdf.js API. +**Getting the code** + +To get a local copy of the current code, clone it using git: + +```bash + git clone git://github.com/andreasgal/pdf.js.git pdfjs + cd pdfjs +``` + +Next, you need to start a local web server as some browsers don't allow opening +PDF files for a file:// url: + +```bash + make server +``` + +If everything worked out, you can now serve + + http://localhost:8888/web/viewer.html + +You can also view all the test pdf files on the right side serving + + http://localhost:8888/test/pdfs/?frame + + + **Hello world** For a "hello world" example, take a look at: @@ -97,6 +123,7 @@ Join our mailing list: Subscribe either using lists.mozilla.org or Google Groups: https://lists.mozilla.org/listinfo/dev-pdf-js + https://groups.google.com/group/mozilla.dev.pdf-js/topics Talk to us on IRC: From 9aee0a2ad39971e19678aa2d897c1d5565f1c04b Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Sun, 25 Sep 2011 11:48:12 +0200 Subject: [PATCH 38/39] Move Contributing section one level up and add a you can just do tests section --- README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index cbde3e93b..f341733f9 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,20 @@ in a custom project. +## Contributing + +pdf.js is a community-driver project, so contributors are always welcome. +Simply fork our repo and contribute away. A great place to start is our +open issues. For better consistency and long-term stability, please do look around the +code and try to follow our conventions. + +If you __don't want to hack__ on the project or have short spare times, you still +can help! Just open PDFs in the +[online demo](http://andreasgal.github.com/pdf.js/web/viewer.html) and report +any breakage in rendering. + + + ## Running the Tests pdf.js comes with browser-level regression tests that allow one to probe @@ -90,16 +104,6 @@ images. The test type `load` simply tests whether the file loads without raising any errors. -## Contributing - -pdf.js is a community-driver project, so contributors are always welcome. -Simply fork our repo and contribute away. A great place to start is our -open issues. - -For better consistency and long-term stability, please do look around the -code and try to follow our conventions. - - ## Additional resources Our demo site is here: From 4d7ddefc4f0a3c3a3b50a97dc470f9f650fae9bf Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Sun, 25 Sep 2011 12:04:35 +0200 Subject: [PATCH 39/39] Add some external files for reading to the Readme.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index f341733f9..f5d4eee9d 100644 --- a/README.md +++ b/README.md @@ -133,3 +133,22 @@ Subscribe either using lists.mozilla.org or Google Groups: Talk to us on IRC: #pdfjs on irc.mozilla.org + +## Additional resources to understand the structure of PDF + +A really basic overview of PDF is described here: + + http://partners.adobe.com/public/developer/en/livecycle/lc_pdf_overview_format.pdf + +A more detailed file example: + + http://gnupdf.org/Introduction_to_PDF + +The PDF specification itself is an ISO and not free available. However, there is +a "PDF Reference" from Adobe: + + http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf + +Recommanded chapters to read: "2. Overview", "3.4 File Structure", +"4.1 Graphics Objects" that lists the PDF commands. +