Merge pull request #13385 from Snuffleupagus/operator_list-class
Convert `src/core/operator_list.js` to use standard classes
This commit is contained in:
commit
35c82af446
@ -13,10 +13,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert, ImageKind, OPS, warn } from "../shared/util.js";
|
import { assert, ImageKind, OPS, shadow, warn } from "../shared/util.js";
|
||||||
|
|
||||||
const QueueOptimizer = (function QueueOptimizerClosure() {
|
function addState(parentState, pattern, checkFn, iterateFn, processFn) {
|
||||||
function addState(parentState, pattern, checkFn, iterateFn, processFn) {
|
|
||||||
let state = parentState;
|
let state = parentState;
|
||||||
for (let i = 0, ii = pattern.length - 1; i < ii; i++) {
|
for (let i = 0, ii = pattern.length - 1; i < ii; i++) {
|
||||||
const item = pattern[i];
|
const item = pattern[i];
|
||||||
@ -27,14 +26,9 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
iterateFn,
|
iterateFn,
|
||||||
processFn,
|
processFn,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePaintSolidColorImageMask(
|
function handlePaintSolidColorImageMask(iFirstSave, count, fnArray, argsArray) {
|
||||||
iFirstSave,
|
|
||||||
count,
|
|
||||||
fnArray,
|
|
||||||
argsArray
|
|
||||||
) {
|
|
||||||
// Handles special case of mainly LaTeX documents which use image masks to
|
// Handles special case of mainly LaTeX documents which use image masks to
|
||||||
// draw lines with the current fill style.
|
// draw lines with the current fill style.
|
||||||
// 'count' groups of (save, transform, paintImageMaskXObject, restore)+
|
// 'count' groups of (save, transform, paintImageMaskXObject, restore)+
|
||||||
@ -57,13 +51,13 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return count - i;
|
return count - i;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InitialState = [];
|
const InitialState = [];
|
||||||
|
|
||||||
// This replaces (save, transform, paintInlineImageXObject, restore)+
|
// This replaces (save, transform, paintInlineImageXObject, restore)+
|
||||||
// sequences with one |paintInlineImageXObjectGroup| operation.
|
// sequences with one |paintInlineImageXObjectGroup| operation.
|
||||||
addState(
|
addState(
|
||||||
InitialState,
|
InitialState,
|
||||||
[OPS.save, OPS.transform, OPS.paintInlineImageXObject, OPS.restore],
|
[OPS.save, OPS.transform, OPS.paintInlineImageXObject, OPS.restore],
|
||||||
null,
|
null,
|
||||||
@ -175,12 +169,12 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
|
|
||||||
return iFirstSave + 1;
|
return iFirstSave + 1;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// This replaces (save, transform, paintImageMaskXObject, restore)+
|
// This replaces (save, transform, paintImageMaskXObject, restore)+
|
||||||
// sequences with one |paintImageMaskXObjectGroup| or one
|
// sequences with one |paintImageMaskXObjectGroup| or one
|
||||||
// |paintImageMaskXObjectRepeat| operation.
|
// |paintImageMaskXObjectRepeat| operation.
|
||||||
addState(
|
addState(
|
||||||
InitialState,
|
InitialState,
|
||||||
[OPS.save, OPS.transform, OPS.paintImageMaskXObject, OPS.restore],
|
[OPS.save, OPS.transform, OPS.paintImageMaskXObject, OPS.restore],
|
||||||
null,
|
null,
|
||||||
@ -297,20 +291,19 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
|
|
||||||
return iFirstSave + 1;
|
return iFirstSave + 1;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// This replaces (save, transform, paintImageXObject, restore)+ sequences
|
// This replaces (save, transform, paintImageXObject, restore)+ sequences
|
||||||
// with one paintImageXObjectRepeat operation, if the |transform| and
|
// with one paintImageXObjectRepeat operation, if the |transform| and
|
||||||
// |paintImageXObjectRepeat| ops are appropriate.
|
// |paintImageXObjectRepeat| ops are appropriate.
|
||||||
addState(
|
addState(
|
||||||
InitialState,
|
InitialState,
|
||||||
[OPS.save, OPS.transform, OPS.paintImageXObject, OPS.restore],
|
[OPS.save, OPS.transform, OPS.paintImageXObject, OPS.restore],
|
||||||
function (context) {
|
function (context) {
|
||||||
const argsArray = context.argsArray;
|
const argsArray = context.argsArray;
|
||||||
const iFirstTransform = context.iCurr - 2;
|
const iFirstTransform = context.iCurr - 2;
|
||||||
return (
|
return (
|
||||||
argsArray[iFirstTransform][1] === 0 &&
|
argsArray[iFirstTransform][1] === 0 && argsArray[iFirstTransform][2] === 0
|
||||||
argsArray[iFirstTransform][2] === 0
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function iterateImageGroup(context, i) {
|
function iterateImageGroup(context, i) {
|
||||||
@ -397,12 +390,12 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
|
|
||||||
return iFirstSave + 1;
|
return iFirstSave + 1;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// This replaces (beginText, setFont, setTextMatrix, showText, endText)+
|
// This replaces (beginText, setFont, setTextMatrix, showText, endText)+
|
||||||
// sequences with (beginText, setFont, (setTextMatrix, showText)+, endText)+
|
// sequences with (beginText, setFont, (setTextMatrix, showText)+, endText)+
|
||||||
// sequences, if the font for each one is the same.
|
// sequences, if the font for each one is the same.
|
||||||
addState(
|
addState(
|
||||||
InitialState,
|
InitialState,
|
||||||
[OPS.beginText, OPS.setFont, OPS.setTextMatrix, OPS.showText, OPS.endText],
|
[OPS.beginText, OPS.setFont, OPS.setTextMatrix, OPS.showText, OPS.endText],
|
||||||
null,
|
null,
|
||||||
@ -489,11 +482,29 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
|
|
||||||
return iEndText + 1;
|
return iEndText + 1;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
class NullOptimizer {
|
||||||
function QueueOptimizer(queue) {
|
constructor(queue) {
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_optimize() {}
|
||||||
|
|
||||||
|
push(fn, args) {
|
||||||
|
this.queue.fnArray.push(fn);
|
||||||
|
this.queue.argsArray.push(args);
|
||||||
|
this._optimize();
|
||||||
|
}
|
||||||
|
|
||||||
|
flush() {}
|
||||||
|
|
||||||
|
reset() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class QueueOptimizer extends NullOptimizer {
|
||||||
|
constructor(queue) {
|
||||||
|
super(queue);
|
||||||
this.state = null;
|
this.state = null;
|
||||||
this.context = {
|
this.context = {
|
||||||
iCurr: 0,
|
iCurr: 0,
|
||||||
@ -504,7 +515,6 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
this.lastProcessed = 0;
|
this.lastProcessed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueOptimizer.prototype = {
|
|
||||||
_optimize() {
|
_optimize() {
|
||||||
// Process new fnArray item(s) chunk.
|
// Process new fnArray item(s) chunk.
|
||||||
const fnArray = this.queue.fnArray;
|
const fnArray = this.queue.fnArray;
|
||||||
@ -557,13 +567,7 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
this.state = state;
|
this.state = state;
|
||||||
this.match = match;
|
this.match = match;
|
||||||
this.lastProcessed = i;
|
this.lastProcessed = i;
|
||||||
},
|
}
|
||||||
|
|
||||||
push(fn, args) {
|
|
||||||
this.queue.fnArray.push(fn);
|
|
||||||
this.queue.argsArray.push(args);
|
|
||||||
this._optimize();
|
|
||||||
},
|
|
||||||
|
|
||||||
flush() {
|
flush() {
|
||||||
while (this.match) {
|
while (this.match) {
|
||||||
@ -574,43 +578,26 @@ const QueueOptimizer = (function QueueOptimizerClosure() {
|
|||||||
// Repeat optimization until all chunks are exhausted.
|
// Repeat optimization until all chunks are exhausted.
|
||||||
this._optimize();
|
this._optimize();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.state = null;
|
this.state = null;
|
||||||
this.match = null;
|
this.match = null;
|
||||||
this.lastProcessed = 0;
|
this.lastProcessed = 0;
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
return QueueOptimizer;
|
|
||||||
})();
|
|
||||||
|
|
||||||
const NullOptimizer = (function NullOptimizerClosure() {
|
class OperatorList {
|
||||||
// eslint-disable-next-line no-shadow
|
static get CHUNK_SIZE() {
|
||||||
function NullOptimizer(queue) {
|
return shadow(this, "CHUNK_SIZE", 1000);
|
||||||
this.queue = queue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NullOptimizer.prototype = {
|
// Close to chunk size.
|
||||||
push(fn, args) {
|
static get CHUNK_SIZE_ABOUT() {
|
||||||
this.queue.fnArray.push(fn);
|
return shadow(this, "CHUNK_SIZE_ABOUT", OperatorList.CHUNK_SIZE - 5);
|
||||||
this.queue.argsArray.push(args);
|
}
|
||||||
},
|
|
||||||
|
|
||||||
flush() {},
|
constructor(intent, streamSink) {
|
||||||
|
|
||||||
reset() {},
|
|
||||||
};
|
|
||||||
|
|
||||||
return NullOptimizer;
|
|
||||||
})();
|
|
||||||
|
|
||||||
const OperatorList = (function OperatorListClosure() {
|
|
||||||
const CHUNK_SIZE = 1000;
|
|
||||||
const CHUNK_SIZE_ABOUT = CHUNK_SIZE - 5; // close to chunk size
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
|
||||||
function OperatorList(intent, streamSink) {
|
|
||||||
this._streamSink = streamSink;
|
this._streamSink = streamSink;
|
||||||
this.fnArray = [];
|
this.fnArray = [];
|
||||||
this.argsArray = [];
|
this.argsArray = [];
|
||||||
@ -625,14 +612,13 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
this._resolved = streamSink ? null : Promise.resolve();
|
this._resolved = streamSink ? null : Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
OperatorList.prototype = {
|
|
||||||
get length() {
|
get length() {
|
||||||
return this.argsArray.length;
|
return this.argsArray.length;
|
||||||
},
|
}
|
||||||
|
|
||||||
get ready() {
|
get ready() {
|
||||||
return this._resolved || this._streamSink.ready;
|
return this._resolved || this._streamSink.ready;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {number} The total length of the entire operator list, since
|
* @type {number} The total length of the entire operator list, since
|
||||||
@ -640,23 +626,23 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
*/
|
*/
|
||||||
get totalLength() {
|
get totalLength() {
|
||||||
return this._totalLength + this.length;
|
return this._totalLength + this.length;
|
||||||
},
|
}
|
||||||
|
|
||||||
addOp(fn, args) {
|
addOp(fn, args) {
|
||||||
this.optimizer.push(fn, args);
|
this.optimizer.push(fn, args);
|
||||||
this.weight++;
|
this.weight++;
|
||||||
if (this._streamSink) {
|
if (this._streamSink) {
|
||||||
if (this.weight >= CHUNK_SIZE) {
|
if (this.weight >= OperatorList.CHUNK_SIZE) {
|
||||||
this.flush();
|
this.flush();
|
||||||
} else if (
|
} else if (
|
||||||
this.weight >= CHUNK_SIZE_ABOUT &&
|
this.weight >= OperatorList.CHUNK_SIZE_ABOUT &&
|
||||||
(fn === OPS.restore || fn === OPS.endText)
|
(fn === OPS.restore || fn === OPS.endText)
|
||||||
) {
|
) {
|
||||||
// heuristic to flush on boundary of restore or endText
|
// Heuristic to flush on boundary of restore or endText.
|
||||||
this.flush();
|
this.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
addDependency(dependency) {
|
addDependency(dependency) {
|
||||||
if (this.dependencies.has(dependency)) {
|
if (this.dependencies.has(dependency)) {
|
||||||
@ -664,13 +650,13 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
}
|
}
|
||||||
this.dependencies.add(dependency);
|
this.dependencies.add(dependency);
|
||||||
this.addOp(OPS.dependency, [dependency]);
|
this.addOp(OPS.dependency, [dependency]);
|
||||||
},
|
}
|
||||||
|
|
||||||
addDependencies(dependencies) {
|
addDependencies(dependencies) {
|
||||||
for (const dependency of dependencies) {
|
for (const dependency of dependencies) {
|
||||||
this.addDependency(dependency);
|
this.addDependency(dependency);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
addOpList(opList) {
|
addOpList(opList) {
|
||||||
if (!(opList instanceof OperatorList)) {
|
if (!(opList instanceof OperatorList)) {
|
||||||
@ -683,7 +669,7 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
for (let i = 0, ii = opList.length; i < ii; i++) {
|
for (let i = 0, ii = opList.length; i < ii; i++) {
|
||||||
this.addOp(opList.fnArray[i], opList.argsArray[i]);
|
this.addOp(opList.fnArray[i], opList.argsArray[i]);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
getIR() {
|
getIR() {
|
||||||
return {
|
return {
|
||||||
@ -691,7 +677,7 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
argsArray: this.argsArray,
|
argsArray: this.argsArray,
|
||||||
length: this.length,
|
length: this.length,
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
|
|
||||||
get _transfers() {
|
get _transfers() {
|
||||||
const transfers = [];
|
const transfers = [];
|
||||||
@ -701,7 +687,7 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
case OPS.paintInlineImageXObject:
|
case OPS.paintInlineImageXObject:
|
||||||
case OPS.paintInlineImageXObjectGroup:
|
case OPS.paintInlineImageXObjectGroup:
|
||||||
case OPS.paintImageMaskXObject:
|
case OPS.paintImageMaskXObject:
|
||||||
const arg = argsArray[i][0]; // first param in imgData
|
const arg = argsArray[i][0]; // First parameter in imgData.
|
||||||
|
|
||||||
if (
|
if (
|
||||||
typeof PDFJSDev === "undefined" ||
|
typeof PDFJSDev === "undefined" ||
|
||||||
@ -719,7 +705,7 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return transfers;
|
return transfers;
|
||||||
},
|
}
|
||||||
|
|
||||||
flush(lastChunk = false) {
|
flush(lastChunk = false) {
|
||||||
this.optimizer.flush();
|
this.optimizer.flush();
|
||||||
@ -742,10 +728,7 @@ const OperatorList = (function OperatorListClosure() {
|
|||||||
this.argsArray.length = 0;
|
this.argsArray.length = 0;
|
||||||
this.weight = 0;
|
this.weight = 0;
|
||||||
this.optimizer.reset();
|
this.optimizer.reset();
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return OperatorList;
|
|
||||||
})();
|
|
||||||
|
|
||||||
export { OperatorList };
|
export { OperatorList };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user