Merge commit 'e5d79fd0da5a0dab8b717062651c2fbd658a4b51'

This commit is contained in:
Adil Allawi 2011-10-05 08:42:54 +01:00
commit 3b3f134e35
10 changed files with 347 additions and 127 deletions

View File

@ -80,7 +80,7 @@ You can add your name to it! :)
## Running the Tests ## Running the tests
pdf.js comes with browser-level regression tests that allow one to probe pdf.js comes with browser-level regression tests that allow one to probe
whether it's able to successfully parse PDFs, as well as compare its output whether it's able to successfully parse PDFs, as well as compare its output
@ -106,6 +106,16 @@ images. The test type `load` simply tests whether the file loads without
raising any errors. raising any errors.
## Running tests through our bot
If you are a reviewer, you can use our remote bot to issue comprehensive tests
against reference images before merging pull requests.
See the bot repo for details:
+ https://github.com/arturadib/pdf.js-bot
## Additional resources ## Additional resources
Our demo site is here: Our demo site is here:
@ -136,7 +146,7 @@ Follow us on twitter: @pdfjs
## Additional resources to understand the structure of PDF ## PDF-related resources
A really basic overview of PDF is described here: A really basic overview of PDF is described here:

View File

@ -62,7 +62,7 @@ function loadDocument(aWindow, aDocumentUrl) {
} }
let WebProgressListener = { let WebProgressListener = {
init: function(aWindow, aUrl) { init: function WebProgressListenerInit(aWindow, aUrl) {
this._locationHasChanged = false; this._locationHasChanged = false;
this._documentUrl = aUrl; this._documentUrl = aUrl;

View File

@ -415,6 +415,8 @@ var Font = (function Font() {
var constructor = function font_constructor(name, file, properties) { var constructor = function font_constructor(name, file, properties) {
this.name = name; this.name = name;
this.encoding = properties.encoding; this.encoding = properties.encoding;
this.coded = properties.coded;
this.resources = properties.resources;
this.sizes = []; this.sizes = [];
var names = name.split('+'); var names = name.split('+');
@ -429,6 +431,9 @@ var Font = (function Font() {
this.loading = false; this.loading = false;
return; return;
} }
this.fontMatrix = properties.fontMatrix;
if (properties.type == 'Type3')
return;
// Trying to fix encoding using glyph widths and CIDSystemInfo. // Trying to fix encoding using glyph widths and CIDSystemInfo.
this.fixWidths(properties); this.fixWidths(properties);
@ -483,7 +488,7 @@ var Font = (function Font() {
this.data = data; this.data = data;
this.type = type; this.type = type;
this.textMatrix = properties.textMatrix; this.fontMatrix = properties.fontMatrix;
this.defaultWidth = properties.defaultWidth; this.defaultWidth = properties.defaultWidth;
this.loadedName = getUniqueName(); this.loadedName = getUniqueName();
this.composite = properties.composite; this.composite = properties.composite;
@ -2009,7 +2014,7 @@ var Type1Parser = function type1Parser() {
// Make the angle into the right direction // Make the angle into the right direction
matrix[2] *= -1; matrix[2] *= -1;
properties.textMatrix = matrix; properties.fontMatrix = matrix;
break; break;
case '/Encoding': case '/Encoding':
var size = parseInt(getToken(), 10); var size = parseInt(getToken(), 10);

172
pdf.js
View File

@ -4557,6 +4557,7 @@ var PartialEvaluator = (function partialEvaluator() {
baseEncoding = Encodings.WinAnsiEncoding.slice(); baseEncoding = Encodings.WinAnsiEncoding.slice();
break; break;
case 'Type1': case 'Type1':
case 'Type3':
baseEncoding = Encodings.StandardEncoding.slice(); baseEncoding = Encodings.StandardEncoding.slice();
break; break;
default: default:
@ -4744,36 +4745,43 @@ var PartialEvaluator = (function partialEvaluator() {
composite = true; composite = true;
} }
// Before PDF 1.5 if the font was one of the base 14 fonts, having a
// FontDescriptor was not required.
// This case is here for compatibility.
var descriptor = xref.fetchIfRef(dict.get('FontDescriptor')); var descriptor = xref.fetchIfRef(dict.get('FontDescriptor'));
if (!descriptor) { if (!descriptor) {
// Note for Type3 fonts: it has no no base font, feeding default if (type.name == 'Type3') {
// font name and trying to get font metrics as the same way as for // FontDescriptor is only required for Type3 fonts when the document
// a font without descriptor. // is a tagged pdf. Create a barbebones one to get by.
var baseFontName = dict.get('BaseFont') || new Name('sans-serif'); descriptor = new Dict();
descriptor.set('FontName', new Name(type.name));
} else {
// Before PDF 1.5 if the font was one of the base 14 fonts, having a
// FontDescriptor was not required.
// This case is here for compatibility.
var baseFontName = dict.get('BaseFont');
if (!isName(baseFontName))
return null;
// Using base font name as a font name. // Using base font name as a font name.
baseFontName = baseFontName.name.replace(/,/g, '_'); baseFontName = baseFontName.name.replace(/,/g, '_');
var metricsAndMap = this.getBaseFontMetricsAndMap(baseFontName); var metricsAndMap = this.getBaseFontMetricsAndMap(baseFontName);
var properties = { var properties = {
type: type.name, type: type.name,
encoding: metricsAndMap.map, encoding: metricsAndMap.map,
differences: [], differences: [],
widths: metricsAndMap.widths, widths: metricsAndMap.widths,
defaultWidth: metricsAndMap.defaultWidth, defaultWidth: metricsAndMap.defaultWidth,
firstChar: 0, firstChar: 0,
lastChar: 256 lastChar: 256
}; };
this.extractEncoding(dict, xref, properties); this.extractEncoding(dict, xref, properties);
return {
name: baseFontName,
dict: baseDict,
properties: properties
};
}
return {
name: baseFontName,
dict: baseDict,
properties: properties
};
} }
// According to the spec if 'FontDescriptor' is declared, 'FirstChar', // According to the spec if 'FontDescriptor' is declared, 'FirstChar',
@ -4832,7 +4840,7 @@ var PartialEvaluator = (function partialEvaluator() {
length2: length2, length2: length2,
composite: composite, composite: composite,
fixedPitch: false, fixedPitch: false,
textMatrix: IDENTITY_MATRIX, fontMatrix: dict.get('FontMatrix') || IDENTITY_MATRIX,
firstChar: firstChar || 0, firstChar: firstChar || 0,
lastChar: lastChar || 256, lastChar: lastChar || 256,
bbox: descriptor.get('FontBBox'), bbox: descriptor.get('FontBBox'),
@ -4845,10 +4853,24 @@ var PartialEvaluator = (function partialEvaluator() {
italicAngle: descriptor.get('ItalicAngle'), italicAngle: descriptor.get('ItalicAngle'),
differences: [], differences: [],
widths: glyphWidths, widths: glyphWidths,
encoding: encoding encoding: encoding,
coded: false
}; };
properties.glyphs = this.extractEncoding(dict, xref, properties); properties.glyphs = this.extractEncoding(dict, xref, properties);
if (type.name === 'Type3') {
properties.coded = true;
var charProcs = xref.fetchIfRef(dict.get('CharProcs'));
var fontResources = xref.fetchIfRef(dict.get('Resources')) || resources;
properties.resources = fontResources;
for (var key in charProcs.map) {
var glyphStream = xref.fetchIfRef(charProcs.map[key]);
properties.glyphs[key].code = this.evaluate(glyphStream,
xref,
fontResources);
}
}
return { return {
name: fontName.name, name: fontName.name,
dict: baseDict, dict: baseDict,
@ -5287,41 +5309,72 @@ var CanvasGraphics = (function canvasGraphics() {
var ctx = this.ctx; var ctx = this.ctx;
var current = this.current; var current = this.current;
var font = current.font; var font = current.font;
ctx.save();
ctx.transform.apply(ctx, current.textMatrix);
ctx.scale(1, -1);
ctx.translate(current.x, -1 * current.y);
ctx.transform.apply(ctx, font.textMatrix || IDENTITY_MATRIX);
var glyphs = font.charsToGlyphs(text); var glyphs = font.charsToGlyphs(text);
var fontSize = current.fontSize; var fontSize = current.fontSize;
var charSpacing = current.charSpacing; var charSpacing = current.charSpacing;
var wordSpacing = current.wordSpacing; var wordSpacing = current.wordSpacing;
var textHScale = current.textHScale; var textHScale = current.textHScale;
ctx.scale(1 / textHScale, 1);
var width = 0;
var glyphsLength = glyphs.length; var glyphsLength = glyphs.length;
for (var i = 0; i < glyphsLength; ++i) { if (font.coded) {
var glyph = glyphs[i]; ctx.save();
if (glyph === null) { ctx.transform.apply(ctx, current.textMatrix);
// word break ctx.translate(current.x, current.y);
width += wordSpacing;
continue; var fontMatrix = font.fontMatrix || IDENTITY_MATRIX;
ctx.scale(1 / textHScale, 1);
for (var i = 0; i < glyphsLength; ++i) {
var glyph = glyphs[i];
if (glyph === null) {
// word break
this.ctx.translate(wordSpacing, 0);
continue;
}
this.save();
ctx.scale(fontSize, fontSize);
ctx.transform.apply(ctx, fontMatrix);
this.execute(glyph.code, this.xref, font.resources);
this.restore();
var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
var width = transformed[0] * fontSize + charSpacing;
ctx.translate(width, 0);
current.x += width;
} }
ctx.restore();
} else {
ctx.save();
ctx.transform.apply(ctx, current.textMatrix);
ctx.scale(1, -1);
ctx.translate(current.x, -1 * current.y);
ctx.transform.apply(ctx, font.fontMatrix || IDENTITY_MATRIX);
var unicode = glyph.unicode; ctx.scale(1 / textHScale, 1);
var char = (unicode >= 0x10000) ?
String.fromCharCode(0xD800 | ((unicode - 0x10000) >> 10),
0xDC00 | (unicode & 0x3FF)) : String.fromCharCode(unicode);
ctx.fillText(char, width, 0); var width = 0;
width += glyph.width * fontSize * 0.001 + charSpacing; for (var i = 0; i < glyphsLength; ++i) {
var glyph = glyphs[i];
if (glyph === null) {
// word break
width += wordSpacing;
continue;
}
var unicode = glyph.unicode;
var char = (unicode >= 0x10000) ?
String.fromCharCode(0xD800 | ((unicode - 0x10000) >> 10),
0xDC00 | (unicode & 0x3FF)) : String.fromCharCode(unicode);
ctx.fillText(char, width, 0);
width += glyph.width * fontSize * 0.001 + charSpacing;
}
current.x += width;
ctx.restore();
} }
current.x += width;
this.ctx.restore();
}, },
showSpacedText: function canvasGraphicsShowSpacedText(arr) { showSpacedText: function canvasGraphicsShowSpacedText(arr) {
var ctx = this.ctx; var ctx = this.ctx;
@ -5359,8 +5412,8 @@ var CanvasGraphics = (function canvasGraphics() {
// Type3 fonts // Type3 fonts
setCharWidth: function canvasGraphicsSetCharWidth(xWidth, yWidth) { setCharWidth: function canvasGraphicsSetCharWidth(xWidth, yWidth) {
TODO('type 3 fonts ("d0" operator) xWidth: ' + xWidth + ' yWidth: ' + // We can safely ignore this since the width should be the same
yWidth); // as the width in the Widths array.
}, },
setCharWidthAndBounds: function canvasGraphicsSetCharWidthAndBounds(xWidth, setCharWidthAndBounds: function canvasGraphicsSetCharWidthAndBounds(xWidth,
yWidth, yWidth,
@ -5368,9 +5421,11 @@ var CanvasGraphics = (function canvasGraphics() {
lly, lly,
urx, urx,
ury) { ury) {
TODO('type 3 fonts ("d1" operator) xWidth: ' + xWidth + ' yWidth: ' + // TODO According to the spec we're also suppose to ignore any operators
yWidth + ' llx: ' + llx + ' lly: ' + lly + ' urx: ' + urx + // that set color or include images while processing this type3 font.
' ury ' + ury); this.rectangle(llx, lly, urx - llx, ury - lly);
this.clip();
this.endPath();
}, },
// Color // Color
@ -6477,6 +6532,7 @@ var PDFImage = (function pdfImage() {
applyStencilMask: function applyStencilMask(buffer, inverseDecode) { applyStencilMask: function applyStencilMask(buffer, inverseDecode) {
var width = this.width, height = this.height; var width = this.width, height = this.height;
var bitStrideLength = (width + 7) >> 3; var bitStrideLength = (width + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(bitStrideLength * height); var imgArray = this.image.getBytes(bitStrideLength * height);
var imgArrayPos = 0; var imgArrayPos = 0;
var i, j, mask, buf; var i, j, mask, buf;
@ -6505,6 +6561,7 @@ var PDFImage = (function pdfImage() {
// rows start at byte boundary; // rows start at byte boundary;
var rowBytes = (width * numComps * bpc + 7) >> 3; var rowBytes = (width * numComps * bpc + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(height * rowBytes); var imgArray = this.image.getBytes(height * rowBytes);
var comps = this.colorSpace.getRgbBuffer( var comps = this.colorSpace.getRgbBuffer(
@ -6532,6 +6589,7 @@ var PDFImage = (function pdfImage() {
// rows start at byte boundary; // rows start at byte boundary;
var rowBytes = (width * numComps * bpc + 7) >> 3; var rowBytes = (width * numComps * bpc + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(height * rowBytes); var imgArray = this.image.getBytes(height * rowBytes);
var comps = this.getComponents(imgArray); var comps = this.getComponents(imgArray);

View File

@ -0,0 +1,141 @@
%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]
/Parent 2 0 R
/Resources 4 0 R
/Contents 5 0 R
>>
endobj
4 0 obj
<<
/Font 6 0 R
/XObject <<
>>
>>
endobj
5 0 obj
<<
/Length 7 0 R
>>
stream
/F0 12 Tf
BT
100 700 Td
(ababab) Tj
ET
endstream
endobj
6 0 obj
<<
/F0 8 0 R
>>
endobj
7 0 obj
39
endobj
8 0 obj
<<
/Type /Font
/Subtype /Type3
/FontBBox [0 0 750 750]
/FontMatrix [0.001 0 0 0.001 0 0]
/CharProcs 9 0 R
/Encoding 10 0 R
/FirstChar 97
/LastChar 98
/Widths [1000 1000]
/FontDescriptor 11 0 R
>>
endobj
9 0 obj
<<
/square 12 0 R
/triangle 13 0 R
>>
endobj
10 0 obj
<<
/Type /Encoding
/Differences [97 /square /triangle]
>>
endobj
11 0 obj
<<
/Type /FontDescriptor
/FontName /SandT
/Flags 262178
/Ascent 0
/CapHeight 0
/Descent 0
/ItalicAngle 0
/StemV 0
/FontBBox [0 0 750 750]
>>
endobj
12 0 obj
<<
/Length 14 0 R
>>
stream
1000 0 0 0 750 750 d1 0 0 750 750 re f
endstream
endobj
13 0 obj
<<
/Length 15 0 R
>>
stream
1000 0 0 0 750 750 d1 0 0 m 375 750 l 750 0 l f
endstream
endobj
14 0 obj
38
endobj
15 0 obj
47
endobj
xref
0 16
0000000000 65535 f
0000000015 00000 n
0000000078 00000 n
0000000135 00000 n
0000000239 00000 n
0000000287 00000 n
0000000381 00000 n
0000000412 00000 n
0000000430 00000 n
0000000641 00000 n
0000000694 00000 n
0000000768 00000 n
0000000925 00000 n
0000001020 00000 n
0000001124 00000 n
0000001143 00000 n
trailer
<<
/Root 1 0 R
/ID [<DD02410A8B7AD4A0EE0D50E4180FABAC> <DD02410A8B7AD4A0EE0D50E4180FABAC>]
/Size 16
>>
startxref
1162
%%EOF

View File

@ -181,5 +181,11 @@
"link": true, "link": true,
"rounds": 1, "rounds": 1,
"type": "eq" "type": "eq"
},
{ "id": "simpletype3font",
"file": "pdfs/simpletype3font.pdf",
"link": false,
"rounds": 1,
"type": "eq"
} }
] ]

View File

@ -232,7 +232,7 @@ function readFontIndexData(aStream, aIsByte) {
return objects; return objects;
} }
var Type2Parser = function(aFilePath) { var Type2Parser = function type2Parser(aFilePath) {
var font = new Dict(); var font = new Dict();
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
@ -292,7 +292,7 @@ var Type2Parser = function(aFilePath) {
} }
} }
this.parse = function(aStream) { this.parse = function type2ParserParse(aStream) {
font.set('major', aStream.getByte()); font.set('major', aStream.getByte());
font.set('minor', aStream.getByte()); font.set('minor', aStream.getByte());
font.set('hdrSize', aStream.getByte()); font.set('hdrSize', aStream.getByte());

View File

@ -4,7 +4,7 @@
'use strict'; 'use strict';
// Checking if the typed arrays are supported // Checking if the typed arrays are supported
(function() { (function checkTypedArrayCompatibility() {
if (typeof Uint8Array !== 'undefined') if (typeof Uint8Array !== 'undefined')
return; return;
@ -12,7 +12,7 @@
return this.slice(start, end); return this.slice(start, end);
} }
function set_function(array, offset) { function setArrayOffset(array, offset) {
if (arguments.length < 2) if (arguments.length < 2)
offset = 0; offset = 0;
for (var i = 0, n = array.length; i < n; ++i, ++offset) for (var i = 0, n = array.length; i < n; ++i, ++offset)
@ -31,7 +31,7 @@
result.subarray = subarray; result.subarray = subarray;
result.buffer = result; result.buffer = result;
result.byteLength = result.length; result.byteLength = result.length;
result.set = set_function; result.set = setArrayOffset;
if (typeof arg1 === 'object' && arg1.buffer) if (typeof arg1 === 'object' && arg1.buffer)
result.buffer = arg1.buffer; result.buffer = arg1.buffer;
@ -49,31 +49,31 @@
})(); })();
// Object.create() ? // Object.create() ?
(function() { (function checkObjectCreateCompatibility() {
if (typeof Object.create !== 'undefined') if (typeof Object.create !== 'undefined')
return; return;
Object.create = function(proto) { Object.create = function objectCreate(proto) {
var constructor = function() {}; var constructor = function objectCreateConstructor() {};
constructor.prototype = proto; constructor.prototype = proto;
return new constructor(); return new constructor();
}; };
})(); })();
// Object.defineProperty() ? // Object.defineProperty() ?
(function() { (function checkObjectDefinePropertyCompatibility() {
if (typeof Object.defineProperty !== 'undefined') if (typeof Object.defineProperty !== 'undefined')
return; return;
Object.defineProperty = function(obj, name, def) { Object.defineProperty = function objectDefineProperty(obj, name, def) {
delete obj[name]; delete obj[name];
if ('get' in def) if ('get' in def)
obj.__defineGetter__(name, def['get']); obj.__defineGetter__(name, def['get']);
if ('set' in def) if ('set' in def)
obj.__defineSetter__(name, def['set']); obj.__defineSetter__(name, def['set']);
if ('value' in def) { if ('value' in def) {
obj.__defineSetter__(name, function(value) { obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
this.__defineGetter__(name, function() { this.__defineGetter__(name, function objectDefinePropertyGetter() {
return value; return value;
}); });
return value; return value;
@ -84,7 +84,7 @@
})(); })();
// No XMLHttpRequest.response ? // No XMLHttpRequest.response ?
(function() { (function checkXMLHttpRequestResponseCompatibility() {
var xhrPrototype = XMLHttpRequest.prototype; var xhrPrototype = XMLHttpRequest.prototype;
if ('response' in xhrPrototype || if ('response' in xhrPrototype ||
'mozResponseArrayBuffer' in xhrPrototype || 'mozResponseArrayBuffer' in xhrPrototype ||
@ -94,7 +94,7 @@
// IE ? // IE ?
if (typeof VBArray !== 'undefined') { if (typeof VBArray !== 'undefined') {
Object.defineProperty(xhrPrototype, 'response', { Object.defineProperty(xhrPrototype, 'response', {
get: function() { get: function xmlHttpRequestResponseGet() {
return new Uint8Array(new VBArray(this.responseBody).toArray()); return new Uint8Array(new VBArray(this.responseBody).toArray());
} }
}); });
@ -122,14 +122,14 @@
})(); })();
// window.btoa (base64 encode function) ? // window.btoa (base64 encode function) ?
(function() { (function checkWindowBtoaCompatibility() {
if ('btoa' in window) if ('btoa' in window)
return; return;
var digits = var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
window.btoa = function(chars) { window.btoa = function windowBtoa(chars) {
var buffer = ''; var buffer = '';
var i, n; var i, n;
for (i = 0, n = chars.length; i < n; i += 3) { for (i = 0, n = chars.length; i < n; i += 3) {
@ -147,13 +147,13 @@
})(); })();
// Function.prototype.bind ? // Function.prototype.bind ?
(function() { (function checkFunctionPrototypeBindCompatibility() {
if (typeof Function.prototype.bind !== 'undefined') if (typeof Function.prototype.bind !== 'undefined')
return; return;
Function.prototype.bind = function(obj) { Function.prototype.bind = function functionPrototypeBind(obj) {
var fn = this, headArgs = Array.prototype.slice.call(arguments, 1); var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
var bound = function() { var bound = function functionPrototypeBindBound() {
var args = Array.prototype.concat.apply(headArgs, arguments); var args = Array.prototype.concat.apply(headArgs, arguments);
return fn.apply(obj, args); return fn.apply(obj, args);
}; };
@ -162,15 +162,15 @@
})(); })();
// IE9 text/html data URI // IE9 text/html data URI
(function() { (function checkDocumentDocumentModeCompatibility() {
if (document.documentMode !== 9) if (document.documentMode !== 9)
return; return;
// overriding the src property // overriding the src property
var originalSrcDescriptor = Object.getOwnPropertyDescriptor( var originalSrcDescriptor = Object.getOwnPropertyDescriptor(
HTMLIFrameElement.prototype, 'src'); HTMLIFrameElement.prototype, 'src');
Object.defineProperty(HTMLIFrameElement.prototype, 'src', { Object.defineProperty(HTMLIFrameElement.prototype, 'src', {
get: function() { return this.$src; }, get: function htmlIFrameElementPrototypeSrcGet() { return this.$src; },
set: function(src) { set: function htmlIFrameElementPrototypeSrcSet(src) {
this.$src = src; this.$src = src;
if (src.substr(0, 14) != 'data:text/html') { if (src.substr(0, 14) != 'data:text/html') {
originalSrcDescriptor.set.call(this, src); originalSrcDescriptor.set.call(this, src);
@ -179,7 +179,7 @@
// for text/html, using blank document and then // for text/html, using blank document and then
// document's open, write, and close operations // document's open, write, and close operations
originalSrcDescriptor.set.call(this, 'about:blank'); originalSrcDescriptor.set.call(this, 'about:blank');
setTimeout((function() { setTimeout((function htmlIFrameElementPrototypeSrcOpenWriteClose() {
var doc = this.contentDocument; var doc = this.contentDocument;
doc.open('text/html'); doc.open('text/html');
doc.write(src.substr(src.indexOf(',') + 1)); doc.write(src.substr(src.indexOf(',') + 1));
@ -189,3 +189,4 @@
enumerable: true enumerable: true
}); });
})(); })();

View File

@ -13,9 +13,9 @@ var kMinScale = 0.25;
var kMaxScale = 4.0; var kMaxScale = 4.0;
var Cache = function(size) { var Cache = function cacheCache(size) {
var data = []; var data = [];
this.push = function(view) { this.push = function cachePush(view) {
data.push(view); data.push(view);
if (data.length > size) if (data.length > size)
data.shift().update(); data.shift().update();
@ -31,7 +31,7 @@ var PDFView = {
currentScale: kDefaultScale, currentScale: kDefaultScale,
initialBookmark: document.location.hash.substring(1), initialBookmark: document.location.hash.substring(1),
setScale: function(val, resetAutoSettings) { setScale: function pdfViewSetScale(val, resetAutoSettings) {
var pages = this.pages; var pages = this.pages;
for (var i = 0; i < pages.length; i++) for (var i = 0; i < pages.length; i++)
pages[i].update(val * kCssUnits); pages[i].update(val * kCssUnits);
@ -47,7 +47,7 @@ var PDFView = {
window.dispatchEvent(event); window.dispatchEvent(event);
}, },
parseScale: function(value, resetAutoSettings) { parseScale: function pdfViewParseScale(value, resetAutoSettings) {
if ('custom' == value) if ('custom' == value)
return; return;
@ -72,12 +72,12 @@ var PDFView = {
} }
}, },
zoomIn: function() { zoomIn: function pdfViewZoomIn() {
var newScale = Math.min(kMaxScale, this.currentScale * kDefaultScaleDelta); var newScale = Math.min(kMaxScale, this.currentScale * kDefaultScaleDelta);
this.setScale(newScale, true); this.setScale(newScale, true);
}, },
zoomOut: function() { zoomOut: function pdfViewZoomOut() {
var newScale = Math.max(kMinScale, this.currentScale / kDefaultScaleDelta); var newScale = Math.max(kMinScale, this.currentScale / kDefaultScaleDelta);
this.setScale(newScale, true); this.setScale(newScale, true);
}, },
@ -104,7 +104,7 @@ var PDFView = {
return currentPageNumber; return currentPageNumber;
}, },
open: function(url, scale) { open: function pdfViewOpen(url, scale) {
if (url.indexOf('http') == 0) if (url.indexOf('http') == 0)
return; return;
@ -124,7 +124,7 @@ var PDFView = {
}); });
}, },
navigateTo: function(dest) { navigateTo: function pdfViewNavigateTo(dest) {
if (typeof dest === 'string') if (typeof dest === 'string')
dest = this.destinations[dest]; dest = this.destinations[dest];
if (!(dest instanceof Array)) if (!(dest instanceof Array))
@ -140,7 +140,7 @@ var PDFView = {
} }
}, },
getDestinationHash: function(dest) { getDestinationHash: function pdfViewGetDestinationHash(dest) {
if (typeof dest === 'string') if (typeof dest === 'string')
return '#' + escape(dest); return '#' + escape(dest);
if (dest instanceof Array) { if (dest instanceof Array) {
@ -155,18 +155,18 @@ var PDFView = {
return ''; return '';
}, },
error: function() { error: function pdfViewError() {
var loadingIndicator = document.getElementById('loading'); var loadingIndicator = document.getElementById('loading');
loadingIndicator.innerHTML = 'Error'; loadingIndicator.innerHTML = 'Error';
}, },
progress: function(level) { progress: function pdfViewProgress(level) {
var percent = Math.round(level * 100); var percent = Math.round(level * 100);
var loadingIndicator = document.getElementById('loading'); var loadingIndicator = document.getElementById('loading');
loadingIndicator.innerHTML = 'Loading... ' + percent + '%'; loadingIndicator.innerHTML = 'Loading... ' + percent + '%';
}, },
load: function(data, scale) { load: function pdfViewLoad(data, scale) {
var loadingIndicator = document.getElementById('loading'); var loadingIndicator = document.getElementById('loading');
loadingIndicator.style.display = 'none'; loadingIndicator.style.display = 'none';
@ -218,7 +218,7 @@ var PDFView = {
this.page = 1; this.page = 1;
}, },
setHash: function(hash) { setHash: function pdfViewSetHash(hash) {
if (!hash) if (!hash)
return; return;
@ -233,7 +233,7 @@ var PDFView = {
PDFView.navigateTo(unescape(hash)); PDFView.navigateTo(unescape(hash));
}, },
switchSidebarView: function(view) { switchSidebarView: function pdfViewSwitchSidebarView(view) {
var thumbsScrollView = document.getElementById('sidebarScrollView'); var thumbsScrollView = document.getElementById('sidebarScrollView');
var outlineScrollView = document.getElementById('outlineScrollView'); var outlineScrollView = document.getElementById('outlineScrollView');
var thumbsSwitchButton = document.getElementById('thumbsSwitch'); var thumbsSwitchButton = document.getElementById('thumbsSwitch');
@ -254,7 +254,7 @@ var PDFView = {
} }
}, },
getVisiblePages: function() { getVisiblePages: function pdfViewGetVisiblePages() {
var pages = this.pages; var pages = this.pages;
var kBottomMargin = 10; var kBottomMargin = 10;
var visiblePages = []; var visiblePages = [];
@ -282,8 +282,8 @@ var PDFView = {
} }
}; };
var PageView = function(container, content, id, pageWidth, pageHeight, var PageView = function pageView(container, content, id, pageWidth, pageHeight,
stats, navigateTo) { stats, navigateTo) {
this.id = id; this.id = id;
this.content = content; this.content = content;
@ -303,7 +303,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
container.appendChild(anchor); container.appendChild(anchor);
container.appendChild(div); container.appendChild(div);
this.update = function(scale) { this.update = function pageViewUpdate(scale) {
this.scale = scale || this.scale; this.scale = scale || this.scale;
div.style.width = (this.width * this.scale) + 'px'; div.style.width = (this.width * this.scale) + 'px';
div.style.height = (this.height * this.scale) + 'px'; div.style.height = (this.height * this.scale) + 'px';
@ -316,7 +316,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
function setupLinks(content, scale) { function setupLinks(content, scale) {
function bindLink(link, dest) { function bindLink(link, dest) {
link.href = PDFView.getDestinationHash(dest); link.href = PDFView.getDestinationHash(dest);
link.onclick = function() { link.onclick = function pageViewSetupLinksOnclick() {
if (dest) if (dest)
PDFView.navigateTo(dest); PDFView.navigateTo(dest);
return false; return false;
@ -337,7 +337,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
} }
} }
this.scrollIntoView = function(dest) { this.scrollIntoView = function pageViewScrollIntoView(dest) {
if (!dest) { if (!dest) {
div.scrollIntoView(true); div.scrollIntoView(true);
return; return;
@ -389,7 +389,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
if (scale) if (scale)
PDFView.setScale(scale, true); PDFView.setScale(scale, true);
setTimeout(function() { setTimeout(function pageViewScrollIntoViewRelayout() {
// letting page to re-layout before scrolling // letting page to re-layout before scrolling
var scale = PDFView.currentScale; var scale = PDFView.currentScale;
var x = Math.min(boundingRect[0].x, boundingRect[1].x); var x = Math.min(boundingRect[0].x, boundingRect[1].x);
@ -410,7 +410,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
}, 0); }, 0);
}; };
this.draw = function() { this.draw = function pageviewDraw() {
if (div.hasChildNodes()) { if (div.hasChildNodes()) {
this.updateStats(); this.updateStats();
return false; return false;
@ -441,7 +441,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
return true; return true;
}; };
this.updateStats = function() { this.updateStats = function pageViewUpdateStats() {
var t1 = stats.compile, t2 = stats.fonts, t3 = stats.render; var t1 = stats.compile, t2 = stats.fonts, t3 = stats.render;
var str = 'Time to compile/fonts/render: ' + var str = 'Time to compile/fonts/render: ' +
(t1 - stats.begin) + '/' + (t2 - t1) + '/' + (t3 - t2) + ' ms'; (t1 - stats.begin) + '/' + (t2 - t1) + '/' + (t3 - t2) + ' ms';
@ -449,7 +449,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
}; };
}; };
var ThumbnailView = function(container, page, id, pageRatio) { var ThumbnailView = function thumbnailView(container, page, id, pageRatio) {
var anchor = document.createElement('a'); var anchor = document.createElement('a');
anchor.href = '#' + id; anchor.href = '#' + id;
anchor.onclick = function stopNivigation() { anchor.onclick = function stopNivigation() {
@ -464,7 +464,7 @@ var ThumbnailView = function(container, page, id, pageRatio) {
anchor.appendChild(div); anchor.appendChild(div);
container.appendChild(anchor); container.appendChild(anchor);
this.draw = function() { this.draw = function thumbnailViewDraw() {
if (div.hasChildNodes()) if (div.hasChildNodes())
return; return;
@ -495,16 +495,16 @@ var ThumbnailView = function(container, page, id, pageRatio) {
div.style.height = (view.height * scaleY) + 'px'; div.style.height = (view.height * scaleY) + 'px';
div.style.lineHeight = (view.height * scaleY) + 'px'; div.style.lineHeight = (view.height * scaleY) + 'px';
page.startRendering(ctx, function() { }); page.startRendering(ctx, function thumbnailViewDrawStartRendering() {});
}; };
}; };
var DocumentOutlineView = function(outline) { var DocumentOutlineView = function documentOutlineView(outline) {
var outlineView = document.getElementById('outlineView'); var outlineView = document.getElementById('outlineView');
function bindItemLink(domObj, item) { function bindItemLink(domObj, item) {
domObj.href = PDFView.getDestinationHash(item.dest); domObj.href = PDFView.getDestinationHash(item.dest);
domObj.onclick = function(e) { domObj.onclick = function documentOutlineViewOnclick(e) {
PDFView.navigateTo(item.dest); PDFView.navigateTo(item.dest);
return false; return false;
}; };
@ -535,7 +535,7 @@ var DocumentOutlineView = function(outline) {
} }
}; };
window.addEventListener('load', function(evt) { window.addEventListener('load', function webViewerLoad(evt) {
var params = document.location.search.substring(1).split('&'); var params = document.location.search.substring(1).split('&');
for (var i = 0; i < params.length; i++) { for (var i = 0; i < params.length; i++) {
var param = params[i].split('='); var param = params[i].split('=');
@ -550,15 +550,15 @@ window.addEventListener('load', function(evt) {
document.getElementById('fileInput').value = null; document.getElementById('fileInput').value = null;
}, true); }, true);
window.addEventListener('pdfload', function(evt) { window.addEventListener('pdfload', function webViewerPdfload(evt) {
PDFView.load(evt.detail); PDFView.load(evt.detail);
}, true); }, true);
window.addEventListener('pdfprogress', function(evt) { window.addEventListener('pdfprogress', function webViewerPdfProgress(evt) {
PDFView.progress(evt.detail); PDFView.progress(evt.detail);
}, true); }, true);
window.addEventListener('pdferror', function(evt) { window.addEventListener('pdferror', function webViewerPdfError(evt) {
PDFView.error(); PDFView.error();
}, true); }, true);
@ -582,29 +582,29 @@ function updateViewarea() {
PDFView.page = firstPage.id; PDFView.page = firstPage.id;
} }
window.addEventListener('scroll', function onscroll(evt) { window.addEventListener('scroll', function webViewerScroll(evt) {
updateViewarea(); updateViewarea();
}, true); }, true);
window.addEventListener('resize', function onscroll(evt) { window.addEventListener('resize', function webViewerResize(evt) {
if (document.getElementById('pageWidthOption').selected || if (document.getElementById('pageWidthOption').selected ||
document.getElementById('pageFitOption').selected) document.getElementById('pageFitOption').selected)
PDFView.parseScale(document.getElementById('scaleSelect').value); PDFView.parseScale(document.getElementById('scaleSelect').value);
updateViewarea(); updateViewarea();
}); });
window.addEventListener('hashchange', function(evt) { window.addEventListener('hashchange', function webViewerHashchange(evt) {
PDFView.setHash(document.location.hash.substring(1)); PDFView.setHash(document.location.hash.substring(1));
}); });
window.addEventListener('change', function(evt) { window.addEventListener('change', function webViewerChange(evt) {
var files = evt.target.files; var files = evt.target.files;
if (!files || files.length == 0) if (!files || files.length == 0)
return; return;
// Read the local file into a Uint8Array. // Read the local file into a Uint8Array.
var fileReader = new FileReader(); var fileReader = new FileReader();
fileReader.onload = function(evt) { fileReader.onload = function webViewerChangeFileReaderOnload(evt) {
var data = evt.target.result; var data = evt.target.result;
var buffer = new ArrayBuffer(data.length); var buffer = new ArrayBuffer(data.length);
var uint8Array = new Uint8Array(buffer); var uint8Array = new Uint8Array(buffer);
@ -622,7 +622,7 @@ window.addEventListener('change', function(evt) {
document.title = file.name; document.title = file.name;
}, true); }, true);
window.addEventListener('transitionend', function(evt) { window.addEventListener('transitionend', function webViewerTransitionend(evt) {
var pageIndex = 0; var pageIndex = 0;
var pagesCount = PDFView.pages.length; var pagesCount = PDFView.pages.length;

View File

@ -9,16 +9,15 @@
var pdfDoc; var pdfDoc;
window.onload = function() { window.onload = function webViewerWorkerOnload() {
window.canvas = document.getElementById("canvas"); window.canvas = document.getElementById("canvas");
window.ctx = canvas.getContext("2d"); window.ctx = canvas.getContext("2d");
pdfDoc = new WorkerPDFDoc(window.canvas); pdfDoc = new WorkerPDFDoc(window.canvas);
pdfDoc.onChangePage = function(numPage) { pdfDoc.onChangePage = function webViewerWorkerOnChangePage(numPage) {
document.getElementById("pageNumber").value = numPage; document.getElementById("pageNumber").value = numPage;
} }
// pdfDoc.open("canvas.pdf", function() { pdfDoc.open("compressed.tracemonkey-pldi-09.pdf", function webViewerWorkerOpen() {
pdfDoc.open("compressed.tracemonkey-pldi-09.pdf", function() {
document.getElementById("numPages").innerHTML = "/" + pdfDoc.numPages; document.getElementById("numPages").innerHTML = "/" + pdfDoc.numPages;
}) })
} }