Merge remote-tracking branch 'origin/decodemap' into smaskscale
This commit is contained in:
commit
01e876f014
@ -1,6 +1,6 @@
|
|||||||
# pdf.js
|
# pdf.js
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@ -205,3 +205,4 @@ a "PDF Reference" from Adobe:
|
|||||||
|
|
||||||
Recommended chapters to read: "2. Overview", "3.4 File Structure",
|
Recommended chapters to read: "2. Overview", "3.4 File Structure",
|
||||||
"4.1 Graphics Objects" that lists the PDF commands.
|
"4.1 Graphics Objects" that lists the PDF commands.
|
||||||
|
|
||||||
|
@ -638,17 +638,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
geometry.hScale = tr[0] - bl[0];
|
geometry.hScale = tr[0] - bl[0];
|
||||||
geometry.vScale = tr[1] - bl[1];
|
geometry.vScale = tr[1] - bl[1];
|
||||||
}
|
}
|
||||||
var spaceGlyph = font.charsToGlyphs(' ');
|
geometry.spaceWidth = font.spaceWidth;
|
||||||
|
|
||||||
// Hack (sometimes space is not encoded)
|
|
||||||
if (spaceGlyph.length === 0 || spaceGlyph[0].width === 0)
|
|
||||||
spaceGlyph = font.charsToGlyphs('i');
|
|
||||||
|
|
||||||
// Fallback
|
|
||||||
if (spaceGlyph.length === 0 || spaceGlyph[0].width === 0)
|
|
||||||
spaceGlyph = [{width: 0}];
|
|
||||||
|
|
||||||
geometry.spaceWidth = spaceGlyph[0].width;
|
|
||||||
return geometry;
|
return geometry;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -687,13 +677,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
var textSelection = textLayer && !skipTextSelection ? true : false;
|
var textSelection = textLayer && !skipTextSelection ? true : false;
|
||||||
var textRenderingMode = current.textRenderingMode;
|
var textRenderingMode = current.textRenderingMode;
|
||||||
|
|
||||||
if (textSelection) {
|
|
||||||
ctx.save();
|
|
||||||
this.applyTextTransforms();
|
|
||||||
text.geom = this.getTextGeometry();
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type3 fonts - each glyph is a "mini-PDF"
|
// Type3 fonts - each glyph is a "mini-PDF"
|
||||||
if (font.coded) {
|
if (font.coded) {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
@ -701,6 +684,13 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
ctx.translate(current.x, current.y);
|
ctx.translate(current.x, current.y);
|
||||||
|
|
||||||
ctx.scale(textHScale, 1);
|
ctx.scale(textHScale, 1);
|
||||||
|
|
||||||
|
if (textSelection) {
|
||||||
|
this.save();
|
||||||
|
ctx.scale(1, -1);
|
||||||
|
text.geom = this.getTextGeometry();
|
||||||
|
this.restore();
|
||||||
|
}
|
||||||
for (var i = 0; i < glyphsLength; ++i) {
|
for (var i = 0; i < glyphsLength; ++i) {
|
||||||
|
|
||||||
var glyph = glyphs[i];
|
var glyph = glyphs[i];
|
||||||
@ -720,7 +710,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
var width = transformed[0] * fontSize + charSpacing;
|
var width = transformed[0] * fontSize + charSpacing;
|
||||||
|
|
||||||
ctx.translate(width, 0);
|
ctx.translate(width, 0);
|
||||||
current.x += width * textHScale2;
|
current.x += width * textHScale;
|
||||||
|
|
||||||
text.str += glyph.unicode;
|
text.str += glyph.unicode;
|
||||||
text.length++;
|
text.length++;
|
||||||
@ -730,6 +720,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
} else {
|
} else {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
this.applyTextTransforms();
|
this.applyTextTransforms();
|
||||||
|
if (textSelection)
|
||||||
|
text.geom = this.getTextGeometry();
|
||||||
|
|
||||||
var width = 0;
|
var width = 0;
|
||||||
for (var i = 0; i < glyphsLength; ++i) {
|
for (var i = 0; i < glyphsLength; ++i) {
|
||||||
@ -780,18 +772,26 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
showSpacedText: function canvasGraphicsShowSpacedText(arr) {
|
showSpacedText: function canvasGraphicsShowSpacedText(arr) {
|
||||||
var ctx = this.ctx;
|
var ctx = this.ctx;
|
||||||
var current = this.current;
|
var current = this.current;
|
||||||
|
var font = current.font;
|
||||||
var fontSize = current.fontSize;
|
var fontSize = current.fontSize;
|
||||||
var textHScale2 = current.textHScale *
|
var textHScale = current.textHScale;
|
||||||
(current.font.fontMatrix || IDENTITY_MATRIX)[0];
|
if (!font.coded)
|
||||||
|
textHScale *= (font.fontMatrix || IDENTITY_MATRIX)[0];
|
||||||
var arrLength = arr.length;
|
var arrLength = arr.length;
|
||||||
var textLayer = this.textLayer;
|
var textLayer = this.textLayer;
|
||||||
var font = current.font;
|
|
||||||
var text = {str: '', length: 0, canvasWidth: 0, geom: {}};
|
var text = {str: '', length: 0, canvasWidth: 0, geom: {}};
|
||||||
var textSelection = textLayer ? true : false;
|
var textSelection = textLayer ? true : false;
|
||||||
|
|
||||||
if (textSelection) {
|
if (textSelection) {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
this.applyTextTransforms();
|
// Type3 fonts - each glyph is a "mini-PDF" (see also showText)
|
||||||
|
if (font.coded) {
|
||||||
|
ctx.transform.apply(ctx, current.textMatrix);
|
||||||
|
ctx.scale(1, -1);
|
||||||
|
ctx.translate(current.x, -1 * current.y);
|
||||||
|
ctx.scale(textHScale, 1);
|
||||||
|
} else
|
||||||
|
this.applyTextTransforms();
|
||||||
text.geom = this.getTextGeometry();
|
text.geom = this.getTextGeometry();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
@ -799,7 +799,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
for (var i = 0; i < arrLength; ++i) {
|
for (var i = 0; i < arrLength; ++i) {
|
||||||
var e = arr[i];
|
var e = arr[i];
|
||||||
if (isNum(e)) {
|
if (isNum(e)) {
|
||||||
var spacingLength = -e * 0.001 * fontSize * textHScale2;
|
var spacingLength = -e * 0.001 * fontSize * textHScale;
|
||||||
current.x += spacingLength;
|
current.x += spacingLength;
|
||||||
|
|
||||||
if (textSelection) {
|
if (textSelection) {
|
||||||
@ -807,9 +807,10 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
text.canvasWidth += spacingLength;
|
text.canvasWidth += spacingLength;
|
||||||
if (e < 0 && text.geom.spaceWidth > 0) { // avoid div by zero
|
if (e < 0 && text.geom.spaceWidth > 0) { // avoid div by zero
|
||||||
var numFakeSpaces = Math.round(-e / text.geom.spaceWidth);
|
var numFakeSpaces = Math.round(-e / text.geom.spaceWidth);
|
||||||
for (var j = 0; j < numFakeSpaces; ++j)
|
if (numFakeSpaces > 0) {
|
||||||
text.str += ' ';
|
text.str += ' ';
|
||||||
text.length += numFakeSpaces > 0 ? 1 : 0;
|
text.length++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isString(e)) {
|
} else if (isString(e)) {
|
||||||
@ -1105,9 +1106,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
|
|
||||||
paintImageXObject: function canvasGraphicsPaintImageXObject(objId) {
|
paintImageXObject: function canvasGraphicsPaintImageXObject(objId) {
|
||||||
var imgData = this.objs.get(objId);
|
var imgData = this.objs.get(objId);
|
||||||
if (!imgData) {
|
if (!imgData)
|
||||||
error('Dependent image isn\'t ready yet');
|
error('Dependent image isn\'t ready yet');
|
||||||
}
|
|
||||||
this.save();
|
this.save();
|
||||||
var ctx = this.ctx;
|
var ctx = this.ctx;
|
||||||
var w = imgData.width;
|
var w = imgData.width;
|
||||||
|
23
src/core.js
23
src/core.js
@ -515,8 +515,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
// Tell the worker the file it was created from.
|
// Tell the worker the file it was created from.
|
||||||
messageHandler.send('workerSrc', workerSrc);
|
messageHandler.send('workerSrc', workerSrc);
|
||||||
|
|
||||||
messageHandler.on('test', function pdfDocTest(message) {
|
messageHandler.on('test', function pdfDocTest(supportTypedArray) {
|
||||||
var supportTypedArray = message.data;
|
|
||||||
if (supportTypedArray) {
|
if (supportTypedArray) {
|
||||||
this.worker = worker;
|
this.worker = worker;
|
||||||
this.setupMessageHandler(messageHandler);
|
this.setupMessageHandler(messageHandler);
|
||||||
@ -554,8 +553,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
setupMessageHandler: function(messageHandler) {
|
setupMessageHandler: function(messageHandler) {
|
||||||
this.messageHandler = messageHandler;
|
this.messageHandler = messageHandler;
|
||||||
|
|
||||||
messageHandler.on('page', function pdfDocPage(message) {
|
messageHandler.on('page', function pdfDocPage(data) {
|
||||||
var data = message.data;
|
|
||||||
var pageNum = data.pageNum;
|
var pageNum = data.pageNum;
|
||||||
var page = this.pageCache[pageNum];
|
var page = this.pageCache[pageNum];
|
||||||
var depFonts = data.depFonts;
|
var depFonts = data.depFonts;
|
||||||
@ -563,8 +561,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
|
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('obj', function pdfDocObj(message) {
|
messageHandler.on('obj', function pdfDocObj(data) {
|
||||||
var data = message.data;
|
|
||||||
var id = data[0];
|
var id = data[0];
|
||||||
var type = data[1];
|
var type = data[1];
|
||||||
|
|
||||||
@ -601,8 +598,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('font_ready', function pdfDocFontReady(message) {
|
messageHandler.on('font_ready', function pdfDocFontReady(data) {
|
||||||
var data = message.data;
|
|
||||||
var id = data[0];
|
var id = data[0];
|
||||||
var font = new FontShape(data[1]);
|
var font = new FontShape(data[1]);
|
||||||
|
|
||||||
@ -614,8 +610,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
messageHandler.on('page_error', function pdfDocError(message) {
|
messageHandler.on('page_error', function pdfDocError(data) {
|
||||||
var data = message.data;
|
|
||||||
var page = this.pageCache[data.pageNum];
|
var page = this.pageCache[data.pageNum];
|
||||||
if (page.callback)
|
if (page.callback)
|
||||||
page.callback(data.error);
|
page.callback(data.error);
|
||||||
@ -623,9 +618,9 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
throw data.error;
|
throw data.error;
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('jpeg_decode', function(message) {
|
messageHandler.on('jpeg_decode', function(data, promise) {
|
||||||
var imageData = message.data[0];
|
var imageData = data[0];
|
||||||
var components = message.data[1];
|
var components = data[1];
|
||||||
if (components != 3 && components != 1)
|
if (components != 3 && components != 1)
|
||||||
error('Only 3 component or 1 component can be returned');
|
error('Only 3 component or 1 component can be returned');
|
||||||
|
|
||||||
@ -652,7 +647,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
buf[j] = data[i];
|
buf[j] = data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message.reply({ data: buf, width: width, height: height});
|
promise.resolve({ data: buf, width: width, height: height});
|
||||||
}).bind(this);
|
}).bind(this);
|
||||||
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
|
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
|
||||||
img.src = src;
|
img.src = src;
|
||||||
|
31
src/fonts.js
31
src/fonts.js
@ -2101,6 +2101,37 @@ var Font = (function FontClosure() {
|
|||||||
return rule;
|
return rule;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get spaceWidth() {
|
||||||
|
// trying to estimate space character width
|
||||||
|
var possibleSpaceReplacements = ['space', 'minus', 'one', 'i'];
|
||||||
|
var width;
|
||||||
|
for (var i = 0, ii = possibleSpaceReplacements.length; i < ii; i++) {
|
||||||
|
var glyphName = possibleSpaceReplacements[i];
|
||||||
|
// if possible, getting width by glyph name
|
||||||
|
if (glyphName in this.widths) {
|
||||||
|
width = this.widths[glyphName];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var glyphUnicode = GlyphsUnicode[glyphName];
|
||||||
|
// finding the charcode via unicodeToCID map
|
||||||
|
var charcode = 0;
|
||||||
|
if (this.composite)
|
||||||
|
charcode = this.unicodeToCID[glyphUnicode];
|
||||||
|
// ... via toUnicode map
|
||||||
|
if (!charcode && 'toUnicode' in this)
|
||||||
|
charcode = this.toUnicode.indexOf(glyphUnicode);
|
||||||
|
// setting it to unicode if negative or undefined
|
||||||
|
if (!(charcode > 0))
|
||||||
|
charcode = glyphUnicode;
|
||||||
|
// trying to get width via charcode
|
||||||
|
width = this.widths[charcode];
|
||||||
|
if (width)
|
||||||
|
break; // the non-zero width found
|
||||||
|
}
|
||||||
|
width = (width || this.defaultWidth) * this.widthMultiplier;
|
||||||
|
return shadow(this, 'spaceWidth', width);
|
||||||
|
},
|
||||||
|
|
||||||
charToGlyph: function fonts_charToGlyph(charcode) {
|
charToGlyph: function fonts_charToGlyph(charcode) {
|
||||||
var unicode, width, codeIRQueue;
|
var unicode, width, codeIRQueue;
|
||||||
|
|
||||||
|
@ -239,7 +239,6 @@ var PDFImage = (function PDFImageClosure() {
|
|||||||
bits = remainingBits;
|
bits = remainingBits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(decodeMap) console.timeEnd('getComps');
|
|
||||||
return output;
|
return output;
|
||||||
},
|
},
|
||||||
getOpacity: function getOpacity() {
|
getOpacity: function getOpacity() {
|
||||||
|
@ -249,7 +249,7 @@ var Parser = (function ParserClosure() {
|
|||||||
if (name == 'CCITTFaxDecode' || name == 'CCF') {
|
if (name == 'CCITTFaxDecode' || name == 'CCF') {
|
||||||
return new CCITTFaxStream(stream, params);
|
return new CCITTFaxStream(stream, params);
|
||||||
}
|
}
|
||||||
TODO('filter "' + name + '" not supported yet');
|
warn('filter "' + name + '" not supported yet');
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3,41 +3,6 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
|
||||||
* A wrapper for data to facilitate adding functionality to messages.
|
|
||||||
*/
|
|
||||||
function Message(data) {
|
|
||||||
this.data = data;
|
|
||||||
this.allowsReply = false;
|
|
||||||
this.combObj;
|
|
||||||
this.id;
|
|
||||||
}
|
|
||||||
Message.prototype = {
|
|
||||||
/**
|
|
||||||
* Reply to the action handler that sent the message.
|
|
||||||
*/
|
|
||||||
reply: function messageReply(data) {
|
|
||||||
if (!this.allowsReply)
|
|
||||||
error('This message does not accept replies.');
|
|
||||||
|
|
||||||
this.combObj.postMessage({
|
|
||||||
isReply: true,
|
|
||||||
callbackId: this.id,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Setup the message to allow a reply.
|
|
||||||
* @param {Object} combObj The handler that has a postMessage function.
|
|
||||||
* @param {String} id The id to identify this message.
|
|
||||||
*/
|
|
||||||
setupReply: function setupReply(combObj, id) {
|
|
||||||
this.allowsReply = true;
|
|
||||||
this.combObj = combObj;
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function MessageHandler(name, comObj) {
|
function MessageHandler(name, comObj) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.comObj = comObj;
|
this.comObj = comObj;
|
||||||
@ -65,11 +30,19 @@ function MessageHandler(name, comObj) {
|
|||||||
}
|
}
|
||||||
} else if (data.action in ah) {
|
} else if (data.action in ah) {
|
||||||
var action = ah[data.action];
|
var action = ah[data.action];
|
||||||
var message = new Message(data.data);
|
if (data.callbackId) {
|
||||||
if (data.callbackId)
|
var promise = new Promise();
|
||||||
message.setupReply(comObj, data.callbackId);
|
promise.then(function(resolvedData) {
|
||||||
|
comObj.postMessage({
|
||||||
action[0].call(action[1], message);
|
isReply: true,
|
||||||
|
callbackId: data.callbackId,
|
||||||
|
data: resolvedData
|
||||||
|
});
|
||||||
|
});
|
||||||
|
action[0].call(action[1], data.data, promise);
|
||||||
|
} else {
|
||||||
|
action[0].call(action[1], data.data);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw 'Unkown action from worker: ' + data.action;
|
throw 'Unkown action from worker: ' + data.action;
|
||||||
}
|
}
|
||||||
@ -108,8 +81,7 @@ var WorkerMessageHandler = {
|
|||||||
setup: function wphSetup(handler) {
|
setup: function wphSetup(handler) {
|
||||||
var pdfDoc = null;
|
var pdfDoc = null;
|
||||||
|
|
||||||
handler.on('test', function wphSetupTest(message) {
|
handler.on('test', function wphSetupTest(data) {
|
||||||
var data = message.data;
|
|
||||||
handler.send('test', data instanceof Uint8Array);
|
handler.send('test', data instanceof Uint8Array);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -120,15 +92,13 @@ var WorkerMessageHandler = {
|
|||||||
// undefined action `workerSrc`.
|
// undefined action `workerSrc`.
|
||||||
});
|
});
|
||||||
|
|
||||||
handler.on('doc', function wphSetupDoc(message) {
|
handler.on('doc', function wphSetupDoc(data) {
|
||||||
var data = message.data;
|
|
||||||
// Create only the model of the PDFDoc, which is enough for
|
// Create only the model of the PDFDoc, which is enough for
|
||||||
// processing the content of the pdf.
|
// processing the content of the pdf.
|
||||||
pdfDoc = new PDFDocModel(new Stream(data));
|
pdfDoc = new PDFDocModel(new Stream(data));
|
||||||
});
|
});
|
||||||
|
|
||||||
handler.on('page_request', function wphSetupPageRequest(message) {
|
handler.on('page_request', function wphSetupPageRequest(pageNum) {
|
||||||
var pageNum = message.data;
|
|
||||||
pageNum = parseInt(pageNum);
|
pageNum = parseInt(pageNum);
|
||||||
|
|
||||||
|
|
||||||
@ -177,8 +147,7 @@ var WorkerMessageHandler = {
|
|||||||
});
|
});
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
handler.on('font', function wphSetupFont(message) {
|
handler.on('font', function wphSetupFont(data) {
|
||||||
var data = message.data;
|
|
||||||
var objId = data[0];
|
var objId = data[0];
|
||||||
var name = data[1];
|
var name = data[1];
|
||||||
var file = data[2];
|
var file = data[2];
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -19,3 +19,4 @@
|
|||||||
!issue840.pdf
|
!issue840.pdf
|
||||||
!scan-bad.pdf
|
!scan-bad.pdf
|
||||||
!freeculture.pdf
|
!freeculture.pdf
|
||||||
|
!issue918.pdf
|
||||||
|
BIN
test/pdfs/issue918.pdf
Normal file
BIN
test/pdfs/issue918.pdf
Normal file
Binary file not shown.
@ -349,6 +349,12 @@
|
|||||||
"pageLimit": 3,
|
"pageLimit": 3,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue918",
|
||||||
|
"file": "pdfs/issue918.pdf",
|
||||||
|
"md5": "d582cc0f2592ae82936589ced2a47e55",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "aboutstacks",
|
{ "id": "aboutstacks",
|
||||||
"file": "pdfs/aboutstacks.pdf",
|
"file": "pdfs/aboutstacks.pdf",
|
||||||
"md5": "6e7c8416a293ba2d83bc8dd20c6ccf51",
|
"md5": "6e7c8416a293ba2d83bc8dd20c6ccf51",
|
||||||
|
@ -537,7 +537,7 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (scale && scale !== PDFView.currentScale)
|
if (scale && scale !== PDFView.currentScale)
|
||||||
PDFView.setScale(scale, true);
|
PDFView.parseScale(scale, true);
|
||||||
|
|
||||||
setTimeout(function pageViewScrollIntoViewRelayout() {
|
setTimeout(function pageViewScrollIntoViewRelayout() {
|
||||||
// letting page to re-layout before scrolling
|
// letting page to re-layout before scrolling
|
||||||
|
Loading…
Reference in New Issue
Block a user