Merge branch 'master' of github.com:andreasgal/pdf.js into predictor
This commit is contained in:
		
						commit
						16c0e0410c
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -12,6 +12,8 @@ PDF_JS_FILES = \ | ||||
| 	pdf.js \
 | ||||
| 	crypto.js \
 | ||||
| 	fonts.js \
 | ||||
| 	metrics.js \
 | ||||
| 	charsets.js \
 | ||||
| 	glyphlist.js \
 | ||||
| 	$(NULL) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										70
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								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: | ||||
| @ -38,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  | ||||
| @ -64,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: | ||||
| @ -97,8 +127,28 @@ 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: | ||||
| 
 | ||||
|   #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. | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										101
									
								
								charsets.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								charsets.js
									
									
									
									
									
										Normal file
									
								
							| @ -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' | ||||
| ]; | ||||
| 
 | ||||
							
								
								
									
										49
									
								
								crypto.js
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								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 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, | ||||
| @ -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([ | ||||
| @ -450,11 +452,11 @@ var CipherTransformFactory = (function() { | ||||
|       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); | ||||
| @ -467,7 +469,7 @@ var CipherTransformFactory = (function() { | ||||
|       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) { | ||||
| @ -542,7 +544,7 @@ var CipherTransformFactory = (function() { | ||||
|       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)); | ||||
|   } | ||||
| 
 | ||||
| @ -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); | ||||
|  | ||||
							
								
								
									
										165
									
								
								fonts.js
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								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,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(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 +220,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 +248,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 += '</script></head><body>'; | ||||
| @ -447,13 +448,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') ? | ||||
|         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 +477,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(); | ||||
| @ -598,7 +600,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; | ||||
|     }); | ||||
| 
 | ||||
| @ -927,7 +929,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); | ||||
|         }); | ||||
| @ -1060,11 +1062,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; | ||||
| @ -1072,10 +1074,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; | ||||
|           }; | ||||
| @ -1322,7 +1324,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
 | ||||
| @ -1344,7 +1346,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
 | ||||
| @ -1367,7 +1369,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); | ||||
| @ -1376,7 +1378,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
 | ||||
| @ -1504,7 +1506,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 | ||||
| @ -2032,7 +2034,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); | ||||
| @ -2232,7 +2234,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
 | ||||
| @ -2309,7 +2311,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
 | ||||
| @ -2362,7 +2364,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(); | ||||
| @ -2387,16 +2389,21 @@ 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; | ||||
| 
 | ||||
|       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, | ||||
| @ -2412,10 +2419,37 @@ 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, | ||||
|                                             privDict, this.properties); | ||||
|                                             privateDict, this.properties); | ||||
| 
 | ||||
|       // create the mapping between charstring and glyph id
 | ||||
|       var glyphIds = []; | ||||
| @ -2432,10 +2466,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; | ||||
| @ -2472,7 +2504,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; | ||||
|     }, | ||||
| 
 | ||||
| @ -2492,8 +2526,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) | ||||
| @ -2538,37 +2572,42 @@ var Type2CFF = (function() { | ||||
|     }, | ||||
| 
 | ||||
|     parseCharsets: function cff_parsecharsets(pos, length, strings) { | ||||
|       if (pos == 0) { | ||||
|         return ISOAdobeCharset.slice(); | ||||
|       } else if (pos == 1) { | ||||
|         return ExpertCharset.slice(); | ||||
|       } else if (pos == 2) { | ||||
|         return ExpertSubsetCharset.slice(); | ||||
|       } | ||||
| 
 | ||||
|       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: | ||||
| @ -2643,20 +2682,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; | ||||
|     }, | ||||
| @ -2702,7 +2741,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; | ||||
|       } | ||||
| @ -2779,7 +2818,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 | ||||
|  | ||||
| @ -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); | ||||
| @ -50,7 +50,21 @@ 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'); | ||||
|   var body = document.body; | ||||
|   while (body.lastChild !== guard) | ||||
|     body.removeChild(body.lastChild); | ||||
| } | ||||
| 
 | ||||
| function nextTask() { | ||||
|   cleanup(); | ||||
| 
 | ||||
|   if (currentTaskIdx == manifest.length) { | ||||
|     return done(); | ||||
|   } | ||||
| @ -62,7 +76,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 +99,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 +144,7 @@ function nextPage(task, loadError) { | ||||
| 
 | ||||
|       page.startRendering( | ||||
|         ctx, | ||||
|         function(e) { | ||||
|         function nextPageStartRendering(e) { | ||||
|           snapshotCurrentPage(task, (!failure && e) ? | ||||
|             ('render : ' + e) : failure); | ||||
|         } | ||||
| @ -146,13 +164,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 +219,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--; | ||||
|     } | ||||
|  | ||||
							
								
								
									
										105
									
								
								test/pdfs/extgstate.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								test/pdfs/extgstate.pdf
									
									
									
									
									
										Normal file
									
								
							| @ -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 [<BFFF29B7D1C75EC69AC080682C2AFC5B> <BFFF29B7D1C75EC69AC080682C2AFC5B>] | ||||
| /Size 11 | ||||
| >> | ||||
| startxref | ||||
| 749 | ||||
| %%EOF | ||||
							
								
								
									
										1
									
								
								test/pdfs/f1040.pdf.link
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/pdfs/f1040.pdf.link
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| http://www.irs.gov/pub/irs-pdf/f1040.pdf | ||||
							
								
								
									
										1
									
								
								test/pdfs/hudsonsurvey.pdf.link
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/pdfs/hudsonsurvey.pdf.link
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| https://issues.apache.org/jira/secure/attachment/12421789/survey.pdf | ||||
| @ -139,5 +139,23 @@ | ||||
|        "link": true, | ||||
|        "rounds": 1, | ||||
|        "type": "load" | ||||
|     }, | ||||
|     {  "id": "f1040", | ||||
|        "file": "pdfs/f1040.pdf", | ||||
|        "link": true, | ||||
|        "rounds": 1, | ||||
|        "type": "load" | ||||
|     }, | ||||
|     {  "id": "hudsonsurvey", | ||||
|        "file": "pdfs/hudsonsurvey.pdf", | ||||
|        "link": true, | ||||
|        "rounds": 1, | ||||
|        "type": "load" | ||||
|     }, | ||||
|     {  "id": "extgstate", | ||||
|        "file": "pdfs/extgstate.pdf", | ||||
|        "link": false, | ||||
|        "rounds": 1, | ||||
|        "type": "load" | ||||
|     } | ||||
| ] | ||||
|  | ||||
| @ -7,12 +7,14 @@ | ||||
|   <script type="text/javascript" src="/crypto.js"></script> | ||||
|   <script type="text/javascript" src="/glyphlist.js"></script> | ||||
|   <script type="text/javascript" src="/metrics.js"></script> | ||||
|   <script type="text/javascript" src="/charsets.js"></script> | ||||
|   <script type="text/javascript" src="driver.js"></script> | ||||
| </head> | ||||
| 
 | ||||
| <body onload="load();"> | ||||
|   <pre style="width:800; height:800; overflow: scroll;"id="stdout"></pre> | ||||
|   <p>Inflight requests: <span id="inFlightCount"></span></p> | ||||
|   <div id="content-end"><!-- cleanup() guard --></div> | ||||
| </body> | ||||
| 
 | ||||
| </html> | ||||
|  | ||||
| @ -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', | ||||
|  | ||||
| @ -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, 10) - 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, 10) - 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; | ||||
| 
 | ||||
|  | ||||
| @ -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 { | ||||
| @ -271,3 +273,8 @@ canvas { | ||||
|     page-break-after: always; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #loading { | ||||
| 	margin: 100px 0; | ||||
| 	text-align: center; | ||||
| } | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|         <script type="text/javascript" src="../crypto.js"></script> | ||||
|         <script type="text/javascript" src="../glyphlist.js"></script> | ||||
|         <script type="text/javascript" src="../metrics.js"></script> | ||||
|         <script type="text/javascript" src="../charsets.js"></script> | ||||
|   </head> | ||||
| 
 | ||||
|   <body> | ||||
| @ -89,7 +90,8 @@ | ||||
|         </div> | ||||
|      </div> | ||||
|     </div> | ||||
| 
 | ||||
|      | ||||
|     <div id="loading">Loading... 0%</div> | ||||
|     <div id="viewer"></div> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @ -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) | ||||
| @ -111,12 +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.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]; | ||||
| @ -163,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; | ||||
| @ -230,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; | ||||
| 
 | ||||
| @ -265,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 - 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 || ''; | ||||
| @ -357,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'); | ||||
| @ -366,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); | ||||
| @ -384,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); | ||||
| @ -400,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; | ||||
| @ -418,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() { }); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user