Merge upstream.
This commit is contained in:
commit
52a4bcbd4f
@ -70,7 +70,7 @@ var CanvasExtraState = (function CanvasExtraStateClosure() {
|
||||
return CanvasExtraState;
|
||||
})();
|
||||
|
||||
function ScratchCanvas(width, height) {
|
||||
function createScratchCanvas(width, height) {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
@ -188,7 +188,7 @@ function addContextCurrentTransform(ctx) {
|
||||
}
|
||||
|
||||
var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
// Defines the time the executeIRQueue is going to be executing
|
||||
// Defines the time the executeOperatorList is going to be executing
|
||||
// before it stops and shedules a continue of execution.
|
||||
var kExecutionTime = 15;
|
||||
|
||||
@ -199,7 +199,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.pendingClip = null;
|
||||
this.res = null;
|
||||
this.xobjs = null;
|
||||
this.ScratchCanvas = ScratchCanvas;
|
||||
this.objs = objs;
|
||||
this.textLayer = textLayer;
|
||||
if (canvasCtx) {
|
||||
@ -229,7 +228,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
'setStrokeColor': true,
|
||||
'setStrokeColorN': true,
|
||||
'setFillColor': true,
|
||||
'setFillColorN_IR': true,
|
||||
'setFillColorN': true,
|
||||
'setStrokeGray': true,
|
||||
'setFillGray': true,
|
||||
'setStrokeRGBColor': true,
|
||||
@ -268,15 +267,16 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.textLayer.beginLayout();
|
||||
},
|
||||
|
||||
executeIRQueue: function canvasGraphicsExecuteIRQueue(codeIR,
|
||||
executeOperatorList: function canvasGraphicsExecuteOperatorList(
|
||||
operatorList,
|
||||
executionStartIdx, continueCallback,
|
||||
stepper) {
|
||||
var argsArray = codeIR.argsArray;
|
||||
var fnArray = codeIR.fnArray;
|
||||
var argsArray = operatorList.argsArray;
|
||||
var fnArray = operatorList.fnArray;
|
||||
var i = executionStartIdx || 0;
|
||||
var argsArrayLen = argsArray.length;
|
||||
|
||||
// Sometimes the IRQueue to execute is empty.
|
||||
// Sometimes the OperatorList to execute is empty.
|
||||
if (argsArrayLen == i) {
|
||||
return i;
|
||||
}
|
||||
@ -314,7 +314,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
|
||||
i++;
|
||||
|
||||
// If the entire IRQueue was executed, stop as were done.
|
||||
// If the entire operatorList was executed, stop as were done.
|
||||
if (i == argsArrayLen) {
|
||||
return i;
|
||||
}
|
||||
@ -327,8 +327,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
return i;
|
||||
}
|
||||
|
||||
// If the IRQueue isn't executed completly yet OR the execution time
|
||||
// was short enough, do another execution round.
|
||||
// If the operatorList isn't executed completely yet OR the execution
|
||||
// time was short enough, do another execution round.
|
||||
}
|
||||
},
|
||||
|
||||
@ -556,7 +556,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.current.leading = -leading;
|
||||
},
|
||||
setFont: function canvasGraphicsSetFont(fontRefName, size) {
|
||||
var fontObj = this.objs.get(fontRefName).fontObj;
|
||||
var fontObj = this.objs.get(fontRefName);
|
||||
var current = this.current;
|
||||
|
||||
if (!fontObj)
|
||||
@ -707,7 +707,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.save();
|
||||
ctx.scale(fontSize, fontSize);
|
||||
ctx.transform.apply(ctx, fontMatrix);
|
||||
this.executeIRQueue(glyph.codeIRQueue);
|
||||
this.executeOperatorList(glyph.operatorList);
|
||||
this.restore();
|
||||
|
||||
var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
|
||||
@ -908,7 +908,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.ctx.strokeStyle = color;
|
||||
this.current.strokeColor = color;
|
||||
},
|
||||
getColorN_IR_Pattern: function canvasGraphicsGetColorN_IR_Pattern(IR, cs) {
|
||||
getColorN_Pattern: function canvasGraphicsGetColorN_Pattern(IR, cs) {
|
||||
if (IR[0] == 'TilingPattern') {
|
||||
var args = IR[1];
|
||||
var base = cs.base;
|
||||
@ -930,11 +930,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
}
|
||||
return pattern;
|
||||
},
|
||||
setStrokeColorN_IR: function canvasGraphicsSetStrokeColorN(/*...*/) {
|
||||
setStrokeColorN: function canvasGraphicsSetStrokeColorN(/*...*/) {
|
||||
var cs = this.current.strokeColorSpace;
|
||||
|
||||
if (cs.name == 'Pattern') {
|
||||
this.current.strokeColor = this.getColorN_IR_Pattern(arguments, cs);
|
||||
this.current.strokeColor = this.getColorN_Pattern(arguments, cs);
|
||||
} else {
|
||||
this.setStrokeColor.apply(this, arguments);
|
||||
}
|
||||
@ -946,11 +946,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.ctx.fillStyle = color;
|
||||
this.current.fillColor = color;
|
||||
},
|
||||
setFillColorN_IR: function canvasGraphicsSetFillColorN(/*...*/) {
|
||||
setFillColorN: function canvasGraphicsSetFillColorN(/*...*/) {
|
||||
var cs = this.current.fillColorSpace;
|
||||
|
||||
if (cs.name == 'Pattern') {
|
||||
this.current.fillColor = this.getColorN_IR_Pattern(arguments, cs);
|
||||
this.current.fillColor = this.getColorN_Pattern(arguments, cs);
|
||||
} else {
|
||||
this.setFillColor.apply(this, arguments);
|
||||
}
|
||||
@ -1116,7 +1116,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
// scale the image to the unit square
|
||||
ctx.scale(1 / w, -1 / h);
|
||||
|
||||
var tmpCanvas = new this.ScratchCanvas(w, h);
|
||||
var tmpCanvas = createScratchCanvas(w, h);
|
||||
var tmpCtx = tmpCanvas.getContext('2d');
|
||||
|
||||
var fillColor = this.current.fillColor;
|
||||
@ -1147,7 +1147,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
// scale the image to the unit square
|
||||
ctx.scale(1 / w, -1 / h);
|
||||
|
||||
var tmpCanvas = new this.ScratchCanvas(w, h);
|
||||
var tmpCanvas = createScratchCanvas(w, h);
|
||||
var tmpCtx = tmpCanvas.getContext('2d');
|
||||
this.putBinaryImageData(tmpCtx, imgData, w, h);
|
||||
|
||||
|
@ -135,6 +135,7 @@ var ColorSpace = (function ColorSpaceClosure() {
|
||||
basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
|
||||
return ['PatternCS', basePatternCS];
|
||||
case 'Indexed':
|
||||
case 'I':
|
||||
var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
|
||||
var hiVal = cs[2] + 1;
|
||||
var lookup = xref.fetchIfRef(cs[3]);
|
||||
|
82
src/core.js
82
src/core.js
@ -170,10 +170,10 @@ var Page = (function PageClosure() {
|
||||
return shadow(this, 'rotate', rotate);
|
||||
},
|
||||
|
||||
startRenderingFromIRQueue: function pageStartRenderingFromIRQueue(
|
||||
IRQueue, fonts) {
|
||||
startRenderingFromOperatorList: function pageStartRenderingFromOperatorList(
|
||||
operatorList, fonts) {
|
||||
var self = this;
|
||||
this.IRQueue = IRQueue;
|
||||
this.operatorList = operatorList;
|
||||
|
||||
var displayContinuation = function pageDisplayContinuation() {
|
||||
// Always defer call to display() to work around bug in
|
||||
@ -184,15 +184,16 @@ var Page = (function PageClosure() {
|
||||
};
|
||||
|
||||
this.ensureFonts(fonts,
|
||||
function pageStartRenderingFromIRQueueEnsureFonts() {
|
||||
function pageStartRenderingFromOperatorListEnsureFonts() {
|
||||
displayContinuation();
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
getIRQueue: function pageGetIRQueue(handler, dependency) {
|
||||
if (this.IRQueue) {
|
||||
getOperatorList: function pageGetOperatorList(handler, dependency) {
|
||||
if (this.operatorList) {
|
||||
// content was compiled
|
||||
return this.IRQueue;
|
||||
return this.operatorList;
|
||||
}
|
||||
|
||||
this.stats.time('Build IR Queue');
|
||||
@ -213,11 +214,10 @@ var Page = (function PageClosure() {
|
||||
|
||||
var pe = this.pe = new PartialEvaluator(
|
||||
xref, handler, 'p' + this.pageNumber + '_');
|
||||
var IRQueue = {};
|
||||
this.IRQueue = pe.getIRQueue(content, resources, IRQueue, dependency);
|
||||
|
||||
this.operatorList = pe.getOperatorList(content, resources, dependency);
|
||||
this.stats.timeEnd('Build IR Queue');
|
||||
return this.IRQueue;
|
||||
return this.operatorList;
|
||||
},
|
||||
|
||||
ensureFonts: function pageEnsureFonts(fonts, callback) {
|
||||
@ -228,14 +228,13 @@ var Page = (function PageClosure() {
|
||||
}
|
||||
|
||||
// Load all the fonts
|
||||
var fontObjs = FontLoader.bind(
|
||||
FontLoader.bind(
|
||||
fonts,
|
||||
function pageEnsureFontsFontObjs(fontObjs) {
|
||||
this.stats.timeEnd('Font Loading');
|
||||
|
||||
callback.call(this);
|
||||
}.bind(this),
|
||||
this.objs
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
|
||||
@ -255,18 +254,19 @@ var Page = (function PageClosure() {
|
||||
rotate: this.rotate });
|
||||
|
||||
var startIdx = 0;
|
||||
var length = this.IRQueue.fnArray.length;
|
||||
var IRQueue = this.IRQueue;
|
||||
var length = this.operatorList.fnArray.length;
|
||||
var operatorList = this.operatorList;
|
||||
var stepper = null;
|
||||
if (PDFJS.pdfBug && StepperManager.enabled) {
|
||||
stepper = StepperManager.create(this.pageNumber);
|
||||
stepper.init(IRQueue);
|
||||
stepper.init(operatorList);
|
||||
stepper.nextBreakPoint = stepper.getNextBreakPoint();
|
||||
}
|
||||
|
||||
var self = this;
|
||||
function next() {
|
||||
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next, stepper);
|
||||
startIdx =
|
||||
gfx.executeOperatorList(operatorList, startIdx, next, stepper);
|
||||
if (startIdx == length) {
|
||||
gfx.endDrawing();
|
||||
stats.timeEnd('Rendering');
|
||||
@ -436,13 +436,14 @@ var Page = (function PageClosure() {
|
||||
startRendering: function pageStartRendering(ctx, callback, textLayer) {
|
||||
var stats = this.stats;
|
||||
stats.time('Overall');
|
||||
// If there is no displayReadyPromise yet, then the IRQueue was never
|
||||
// If there is no displayReadyPromise yet, then the operatorList was never
|
||||
// requested before. Make the request and create the promise.
|
||||
if (!this.displayReadyPromise) {
|
||||
this.pdf.startRendering(this);
|
||||
this.displayReadyPromise = new Promise();
|
||||
}
|
||||
// Once the IRQueue and fonts are loaded, perform the actual rendering.
|
||||
|
||||
// Once the operatorList and fonts are loaded, do the actual rendering.
|
||||
this.displayReadyPromise.then(
|
||||
function pageDisplayReadyPromise() {
|
||||
var gfx = new CanvasGraphics(ctx, this.objs, textLayer);
|
||||
@ -474,9 +475,6 @@ var Page = (function PageClosure() {
|
||||
* Right now there exists one PDFDocModel on the main thread + one object
|
||||
* for each worker. If there is no worker support enabled, there are two
|
||||
* `PDFDocModel` objects on the main thread created.
|
||||
* TODO: Refactor the internal object structure, such that there is no
|
||||
* need for the `PDFDocModel` anymore and there is only one object on the
|
||||
* main thread and not one entire copy on each worker instance.
|
||||
*/
|
||||
var PDFDocModel = (function PDFDocModelClosure() {
|
||||
function PDFDocModel(arg, callback) {
|
||||
@ -645,9 +643,9 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
|
||||
this.data = data;
|
||||
this.stream = stream;
|
||||
this.pdf = new PDFDocModel(stream);
|
||||
this.fingerprint = this.pdf.getFingerprint();
|
||||
this.catalog = this.pdf.catalog;
|
||||
this.pdfModel = new PDFDocModel(stream);
|
||||
this.fingerprint = this.pdfModel.getFingerprint();
|
||||
this.catalog = this.pdfModel.catalog;
|
||||
this.objs = new PDFObjects();
|
||||
|
||||
this.pageCache = [];
|
||||
@ -733,8 +731,9 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
var pageNum = data.pageNum;
|
||||
var page = this.pageCache[pageNum];
|
||||
var depFonts = data.depFonts;
|
||||
|
||||
page.stats.timeEnd('Page Request');
|
||||
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
|
||||
page.startRenderingFromOperatorList(data.operatorList, depFonts);
|
||||
}, this);
|
||||
|
||||
messageHandler.on('obj', function pdfDocObj(data) {
|
||||
@ -761,31 +760,16 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
file = new Stream(file, 0, file.length, fontFileDict);
|
||||
}
|
||||
|
||||
// For now, resolve the font object here direclty. The real font
|
||||
// object is then created in FontLoader.bind().
|
||||
this.objs.resolve(id, {
|
||||
name: name,
|
||||
file: file,
|
||||
properties: properties
|
||||
});
|
||||
// At this point, only the font object is created but the font is
|
||||
// not yet attached to the DOM. This is done in `FontLoader.bind`.
|
||||
var font = new Font(name, file, properties);
|
||||
this.objs.resolve(id, font);
|
||||
break;
|
||||
default:
|
||||
error('Got unkown object type ' + type);
|
||||
}
|
||||
}, this);
|
||||
|
||||
messageHandler.on('font_ready', function pdfDocFontReady(data) {
|
||||
var id = data[0];
|
||||
var font = new FontShape(data[1]);
|
||||
|
||||
// If there is no string, then there is nothing to attach to the DOM.
|
||||
if (!font.str) {
|
||||
this.objs.resolve(id, font);
|
||||
} else {
|
||||
this.objs.setData(id, font);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
messageHandler.on('page_error', function pdfDocError(data) {
|
||||
var page = this.pageCache[data.pageNum];
|
||||
if (page.displayReadyPromise)
|
||||
@ -807,7 +791,7 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
var size = width * height;
|
||||
var rgbaLength = size * 4;
|
||||
var buf = new Uint8Array(size * components);
|
||||
var tmpCanvas = new ScratchCanvas(width, height);
|
||||
var tmpCanvas = createScratchCanvas(width, height);
|
||||
var tmpCtx = tmpCanvas.getContext('2d');
|
||||
tmpCtx.drawImage(img, 0, 0);
|
||||
var data = tmpCtx.getImageData(0, 0, width, height).data;
|
||||
@ -836,7 +820,7 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
},
|
||||
|
||||
get numPages() {
|
||||
return this.pdf.numPages;
|
||||
return this.pdfModel.numPages;
|
||||
},
|
||||
|
||||
startRendering: function pdfDocStartRendering(page) {
|
||||
@ -851,7 +835,7 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
if (this.pageCache[n])
|
||||
return this.pageCache[n];
|
||||
|
||||
var page = this.pdf.getPage(n);
|
||||
var page = this.pdfModel.getPage(n);
|
||||
// Add a reference to the objects such that Page can forward the reference
|
||||
// to the CanvasGraphics and so on.
|
||||
page.objs = this.objs;
|
||||
|
@ -112,8 +112,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
};
|
||||
|
||||
PartialEvaluator.prototype = {
|
||||
getIRQueue: function partialEvaluatorGetIRQueue(stream, resources,
|
||||
queue, dependency) {
|
||||
getOperatorList: function partialEvaluatorGetOperatorList(stream, resources,
|
||||
dependency, queue) {
|
||||
|
||||
var self = this;
|
||||
var xref = this.xref;
|
||||
@ -136,8 +136,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
|
||||
var fontRes = resources.get('Font');
|
||||
|
||||
// TODO: TOASK: Is it possible to get here? If so, what does
|
||||
// args[0].name should be like???
|
||||
assert(fontRes, 'fontRes not available');
|
||||
|
||||
fontRes = xref.fetchIfRef(fontRes);
|
||||
@ -177,7 +175,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
|
||||
// Ensure the font is ready before the font is set
|
||||
// and later on used for drawing.
|
||||
// TODO: This should get insert to the IRQueue only once per
|
||||
// OPTIMIZE: This should get insert to the operatorList only once per
|
||||
// page.
|
||||
insertDependency([loadedName]);
|
||||
return loadedName;
|
||||
@ -239,6 +237,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
}, handler, xref, resources, image, inline);
|
||||
}
|
||||
|
||||
if (!queue)
|
||||
queue = {};
|
||||
|
||||
if (!queue.argsArray) {
|
||||
queue.argsArray = [];
|
||||
}
|
||||
@ -280,9 +281,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
// TODO figure out how to type-check vararg functions
|
||||
|
||||
if ((cmd == 'SCN' || cmd == 'scn') && !args[args.length - 1].code) {
|
||||
// Use the IR version for setStroke/FillColorN.
|
||||
fn += '_IR';
|
||||
|
||||
// compile tiling patterns
|
||||
var patternName = args[args.length - 1];
|
||||
// SCN/scn applies patterns along with normal colors
|
||||
@ -295,15 +293,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
if (typeNum == TILING_PATTERN) {
|
||||
// Create an IR of the pattern code.
|
||||
var depIdx = dependencyArray.length;
|
||||
var queueObj = {};
|
||||
var codeIR = this.getIRQueue(pattern, dict.get('Resources') ||
|
||||
resources, queueObj, dependencyArray);
|
||||
var operatorList = this.getOperatorList(pattern,
|
||||
dict.get('Resources') || resources, dependencyArray);
|
||||
|
||||
// Add the dependencies that are required to execute the
|
||||
// codeIR.
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
args = TilingPattern.getIR(codeIR, dict, args);
|
||||
args = TilingPattern.getIR(operatorList, dict, args);
|
||||
}
|
||||
else if (typeNum == SHADING_PATTERN) {
|
||||
var shading = xref.fetchIfRef(dict.get('Shading'));
|
||||
@ -337,14 +334,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
fnArray.push('paintFormXObjectBegin');
|
||||
argsArray.push([matrix, bbox]);
|
||||
|
||||
// This adds the IRQueue of the xObj to the current queue.
|
||||
// This adds the operatorList of the xObj to the current queue.
|
||||
var depIdx = dependencyArray.length;
|
||||
|
||||
this.getIRQueue(xobj, xobj.dict.get('Resources') || resources,
|
||||
queue, dependencyArray);
|
||||
// Pass in the current `queue` object. That means the `fnArray`
|
||||
// and the `argsArray` in this scope is reused and new commands
|
||||
// are added to them.
|
||||
this.getOperatorList(xobj,
|
||||
xobj.dict.get('Resources') || resources,
|
||||
dependencyArray, queue);
|
||||
|
||||
// Add the dependencies that are required to execute the
|
||||
// codeIR.
|
||||
// operatorList.
|
||||
insertDependency(dependencyArray.slice(depIdx));
|
||||
|
||||
fn = 'paintFormXObjectEnd';
|
||||
@ -454,10 +455,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
fnArray: fnArray,
|
||||
argsArray: argsArray
|
||||
};
|
||||
return queue;
|
||||
},
|
||||
|
||||
extractDataStructures: function
|
||||
@ -858,12 +856,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
var charProcs = xref.fetchIfRef(dict.get('CharProcs'));
|
||||
var fontResources = xref.fetchIfRef(dict.get('Resources')) || resources;
|
||||
properties.resources = fontResources;
|
||||
properties.charProcIRQueues = {};
|
||||
properties.charProcOperatorList = {};
|
||||
for (var key in charProcs.map) {
|
||||
var glyphStream = xref.fetchIfRef(charProcs.map[key]);
|
||||
var queueObj = {};
|
||||
properties.charProcIRQueues[key] =
|
||||
this.getIRQueue(glyphStream, fontResources, queueObj, dependency);
|
||||
properties.charProcOperatorList[key] =
|
||||
this.getOperatorList(glyphStream, fontResources, dependency);
|
||||
}
|
||||
}
|
||||
|
||||
|
60
src/fonts.js
60
src/fonts.js
@ -409,8 +409,8 @@ var FontLoader = {
|
||||
|
||||
bind: function fontLoaderBind(fonts, callback) {
|
||||
function checkFontsLoaded() {
|
||||
for (var i = 0, ii = objs.length; i < ii; i++) {
|
||||
var fontObj = objs[i];
|
||||
for (var i = 0, ii = fonts.length; i < ii; i++) {
|
||||
var fontObj = fonts[i];
|
||||
if (fontObj.loading) {
|
||||
return false;
|
||||
}
|
||||
@ -423,52 +423,45 @@ var FontLoader = {
|
||||
return true;
|
||||
}
|
||||
|
||||
var rules = [], names = [], objs = [];
|
||||
var rules = [], names = [], fontsToLoad = [];
|
||||
var fontCreateTimer = 0;
|
||||
|
||||
for (var i = 0, ii = fonts.length; i < ii; i++) {
|
||||
var font = fonts[i];
|
||||
|
||||
// If there is already a fontObj on the font, then it was loaded/attached
|
||||
// to the page already and we don't have to do anything for this font
|
||||
// here future.
|
||||
if (font.fontObj) {
|
||||
// Add the font to the DOM only once or skip if the font
|
||||
// is already loaded.
|
||||
if (font.attached || font.loading == false) {
|
||||
continue;
|
||||
}
|
||||
font.attached = true;
|
||||
|
||||
var obj = new Font(font.name, font.file, font.properties);
|
||||
|
||||
// Store the fontObj on the font such that `setFont` in CanvasGraphics
|
||||
// can reuse it later again.
|
||||
font.fontObj = obj;
|
||||
|
||||
objs.push(obj);
|
||||
fontsToLoad.push(font);
|
||||
|
||||
var str = '';
|
||||
var data = obj.data;
|
||||
var data = font.data;
|
||||
if (data) {
|
||||
var length = data.length;
|
||||
for (var j = 0; j < length; j++)
|
||||
str += String.fromCharCode(data[j]);
|
||||
|
||||
var rule = isWorker ? obj.bindWorker(str) : obj.bindDOM(str);
|
||||
var rule = font.bindDOM(str);
|
||||
if (rule) {
|
||||
rules.push(rule);
|
||||
names.push(obj.loadedName);
|
||||
names.push(font.loadedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.listeningForFontLoad = false;
|
||||
if (!isWorker && rules.length) {
|
||||
FontLoader.prepareFontLoadEvent(rules, names, objs);
|
||||
FontLoader.prepareFontLoadEvent(rules, names, fontsToLoad);
|
||||
}
|
||||
|
||||
if (!checkFontsLoaded()) {
|
||||
document.documentElement.addEventListener(
|
||||
'pdfjsFontLoad', checkFontsLoaded, false);
|
||||
}
|
||||
|
||||
return objs;
|
||||
},
|
||||
// Set things up so that at least one pdfjsFontLoad event is
|
||||
// dispatched when all the @font-face |rules| for |names| have been
|
||||
@ -476,7 +469,7 @@ var FontLoader = {
|
||||
// has already started in this (outer) document, so that they should
|
||||
// be ordered before the load in the subdocument.
|
||||
prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names,
|
||||
objs) {
|
||||
fonts) {
|
||||
/** 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
|
||||
@ -523,8 +516,8 @@ var FontLoader = {
|
||||
'message',
|
||||
function fontLoaderMessage(e) {
|
||||
var fontNames = JSON.parse(e.data);
|
||||
for (var i = 0, ii = objs.length; i < ii; ++i) {
|
||||
var font = objs[i];
|
||||
for (var i = 0, ii = fonts.length; i < ii; ++i) {
|
||||
var font = fonts[i];
|
||||
font.loading = false;
|
||||
}
|
||||
var evt = document.createEvent('Events');
|
||||
@ -770,7 +763,7 @@ var Font = (function FontClosure() {
|
||||
function Font(name, file, properties) {
|
||||
this.name = name;
|
||||
this.coded = properties.coded;
|
||||
this.charProcIRQueues = properties.charProcIRQueues;
|
||||
this.charProcOperatorList = properties.charProcOperatorList;
|
||||
this.resources = properties.resources;
|
||||
this.sizes = [];
|
||||
|
||||
@ -868,7 +861,7 @@ var Font = (function FontClosure() {
|
||||
this.widthMultiplier = !properties.fontMatrix ? 1.0 :
|
||||
1.0 / properties.fontMatrix[0];
|
||||
this.encoding = properties.baseEncoding;
|
||||
this.loadedName = getUniqueName();
|
||||
this.loadedName = properties.loadedName;
|
||||
this.loading = true;
|
||||
};
|
||||
|
||||
@ -2278,17 +2271,6 @@ var Font = (function FontClosure() {
|
||||
}
|
||||
},
|
||||
|
||||
bindWorker: function font_bindWorker(data) {
|
||||
postMessage({
|
||||
action: 'font',
|
||||
data: {
|
||||
raw: data,
|
||||
fontName: this.loadedName,
|
||||
mimetype: this.mimetype
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
bindDOM: function font_bindDom(data) {
|
||||
var fontName = this.loadedName;
|
||||
|
||||
@ -2342,7 +2324,7 @@ var Font = (function FontClosure() {
|
||||
},
|
||||
|
||||
charToGlyph: function fonts_charToGlyph(charcode) {
|
||||
var fontCharCode, width, codeIRQueue;
|
||||
var fontCharCode, width, operatorList;
|
||||
|
||||
var width = this.widths[charcode];
|
||||
|
||||
@ -2377,7 +2359,7 @@ var Font = (function FontClosure() {
|
||||
break;
|
||||
case 'Type3':
|
||||
var glyphName = this.differences[charcode] || this.encoding[charcode];
|
||||
codeIRQueue = this.charProcIRQueues[glyphName];
|
||||
operatorList = this.charProcOperatorList[glyphName];
|
||||
fontCharCode = charcode;
|
||||
break;
|
||||
case 'TrueType':
|
||||
@ -2420,7 +2402,7 @@ var Font = (function FontClosure() {
|
||||
fontChar: String.fromCharCode(fontCharCode),
|
||||
unicode: unicodeChars,
|
||||
width: width,
|
||||
codeIRQueue: codeIRQueue
|
||||
operatorList: operatorList
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -190,7 +190,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
||||
var MAX_PATTERN_SIZE = 512;
|
||||
|
||||
function TilingPattern(IR, color, ctx, objs) {
|
||||
var IRQueue = IR[2];
|
||||
var operatorList = IR[2];
|
||||
this.matrix = IR[3];
|
||||
var bbox = IR[4];
|
||||
var xstep = IR[5];
|
||||
@ -222,7 +222,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
||||
width = height = MAX_PATTERN_SIZE;
|
||||
}
|
||||
|
||||
var tmpCanvas = new ScratchCanvas(width, height);
|
||||
var tmpCanvas = createScratchCanvas(width, height);
|
||||
|
||||
// set the new canvas element context as the graphics context
|
||||
var tmpCtx = tmpCanvas.getContext('2d');
|
||||
@ -259,12 +259,12 @@ var TilingPattern = (function TilingPatternClosure() {
|
||||
graphics.endPath();
|
||||
}
|
||||
|
||||
graphics.executeIRQueue(IRQueue);
|
||||
graphics.executeOperatorList(operatorList);
|
||||
|
||||
this.canvas = tmpCanvas;
|
||||
}
|
||||
|
||||
TilingPattern.getIR = function tiling_getIR(codeIR, dict, args) {
|
||||
TilingPattern.getIR = function tiling_getIR(operatorList, dict, args) {
|
||||
var matrix = dict.get('Matrix');
|
||||
var bbox = dict.get('BBox');
|
||||
var xstep = dict.get('XStep');
|
||||
@ -272,7 +272,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
||||
var paintType = dict.get('PaintType');
|
||||
|
||||
return [
|
||||
'TilingPattern', args, codeIR, matrix, bbox, xstep, ystep, paintType
|
||||
'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep, paintType
|
||||
];
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,7 @@ MessageHandler.prototype = {
|
||||
|
||||
var WorkerMessageHandler = {
|
||||
setup: function wphSetup(handler) {
|
||||
var pdfDoc = null;
|
||||
var pdfModel = null;
|
||||
|
||||
handler.on('test', function wphSetupTest(data) {
|
||||
handler.send('test', data instanceof Uint8Array);
|
||||
@ -88,7 +88,7 @@ var WorkerMessageHandler = {
|
||||
handler.on('doc', function wphSetupDoc(data) {
|
||||
// Create only the model of the PDFDoc, which is enough for
|
||||
// processing the content of the pdf.
|
||||
pdfDoc = new PDFDocModel(new Stream(data));
|
||||
pdfModel = new PDFDocModel(new Stream(data));
|
||||
});
|
||||
|
||||
handler.on('page_request', function wphSetupPageRequest(pageNum) {
|
||||
@ -103,14 +103,14 @@ var WorkerMessageHandler = {
|
||||
var start = Date.now();
|
||||
|
||||
var dependency = [];
|
||||
var IRQueue = null;
|
||||
var operatorList = null;
|
||||
try {
|
||||
var page = pdfDoc.getPage(pageNum);
|
||||
var page = pdfModel.getPage(pageNum);
|
||||
// Pre compile the pdf page and fetch the fonts/images.
|
||||
IRQueue = page.getIRQueue(handler, dependency);
|
||||
operatorList = page.getOperatorList(handler, dependency);
|
||||
} catch (e) {
|
||||
var minimumStackMessage =
|
||||
'worker.js: while trying to getPage() and getIRQueue()';
|
||||
'worker.js: while trying to getPage() and getOperatorList()';
|
||||
|
||||
// Turn the error into an obj that can be serialized
|
||||
if (typeof e === 'string') {
|
||||
@ -137,8 +137,8 @@ var WorkerMessageHandler = {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('page=%d - getIRQueue: time=%dms, len=%d', pageNum,
|
||||
Date.now() - start, IRQueue.fnArray.length);
|
||||
console.log('page=%d - getOperatorList: time=%dms, len=%d', pageNum,
|
||||
Date.now() - start, operatorList.fnArray.length);
|
||||
|
||||
// Filter the dependecies for fonts.
|
||||
var fonts = {};
|
||||
@ -151,59 +151,10 @@ var WorkerMessageHandler = {
|
||||
|
||||
handler.send('page', {
|
||||
pageNum: pageNum,
|
||||
IRQueue: IRQueue,
|
||||
operatorList: operatorList,
|
||||
depFonts: Object.keys(fonts)
|
||||
});
|
||||
}, this);
|
||||
|
||||
handler.on('font', function wphSetupFont(data) {
|
||||
var objId = data[0];
|
||||
var name = data[1];
|
||||
var file = data[2];
|
||||
var properties = data[3];
|
||||
|
||||
var font = {
|
||||
name: name,
|
||||
file: file,
|
||||
properties: properties
|
||||
};
|
||||
|
||||
// Some fonts don't have a file, e.g. the build in ones like Arial.
|
||||
if (file) {
|
||||
var fontFileDict = new Dict();
|
||||
fontFileDict.map = file.dict.map;
|
||||
|
||||
var fontFile = new Stream(file.bytes, file.start,
|
||||
file.end - file.start, fontFileDict);
|
||||
|
||||
// Check if this is a FlateStream. Otherwise just use the created
|
||||
// Stream one. This makes complex_ttf_font.pdf work.
|
||||
var cmf = file.bytes[0];
|
||||
if ((cmf & 0x0f) == 0x08) {
|
||||
font.file = new FlateStream(fontFile);
|
||||
} else {
|
||||
font.file = fontFile;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = new Font(font.name, font.file, font.properties);
|
||||
|
||||
var str = '';
|
||||
var objData = obj.data;
|
||||
if (objData) {
|
||||
var length = objData.length;
|
||||
for (var j = 0; j < length; ++j)
|
||||
str += String.fromCharCode(objData[j]);
|
||||
}
|
||||
|
||||
obj.str = str;
|
||||
|
||||
// Remove the data array form the font object, as it's not needed
|
||||
// anymore as we sent over the ready str.
|
||||
delete obj.data;
|
||||
|
||||
handler.send('font_ready', [objId, obj]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -20,6 +20,7 @@
|
||||
!scan-bad.pdf
|
||||
!freeculture.pdf
|
||||
!pdfkit_compressed.pdf
|
||||
!TAMReview.pdf
|
||||
!issue918.pdf
|
||||
!issue1249.pdf
|
||||
!smaskdim.pdf
|
||||
|
BIN
test/pdfs/TAMReview.pdf
Normal file
BIN
test/pdfs/TAMReview.pdf
Normal file
Binary file not shown.
@ -472,6 +472,14 @@
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "tamreview",
|
||||
"file": "pdfs/TAMReview.pdf",
|
||||
"md5": "8039aba56790d3597d2bc8c794a51301",
|
||||
"rounds": 1,
|
||||
"pageLimit": 5,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1350",
|
||||
"file": "pdfs/issue1350.pdf",
|
||||
"md5": "92f72a04a4d9d05b2dd433b51f32ab1f",
|
||||
|
Loading…
x
Reference in New Issue
Block a user