[Editor] Add support for printing newly added Ink annotations
This commit is contained in:
parent
8d466f5dac
commit
f27c8c4471
@ -295,6 +295,27 @@ class AnnotationFactory {
|
|||||||
dependencies,
|
dependencies,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async printNewAnnotations(evaluator, task, annotations) {
|
||||||
|
if (!annotations) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const xref = evaluator.xref;
|
||||||
|
const promises = [];
|
||||||
|
for (const annotation of annotations) {
|
||||||
|
switch (annotation.annotationType) {
|
||||||
|
case AnnotationEditorType.FREETEXT:
|
||||||
|
break;
|
||||||
|
case AnnotationEditorType.INK:
|
||||||
|
promises.push(
|
||||||
|
InkAnnotation.createNewPrintAnnotation(annotation, xref)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRgbColor(color, defaultColor = new Uint8ClampedArray(3)) {
|
function getRgbColor(color, defaultColor = new Uint8ClampedArray(3)) {
|
||||||
@ -3621,15 +3642,7 @@ class InkAnnotation extends MarkupAnnotation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async createNewAnnotation(
|
static createInkDict(annotation, xref, { apRef, ap }) {
|
||||||
xref,
|
|
||||||
evaluator,
|
|
||||||
task,
|
|
||||||
annotation,
|
|
||||||
results,
|
|
||||||
others
|
|
||||||
) {
|
|
||||||
const inkRef = xref.getNewRef();
|
|
||||||
const ink = new Dict(xref);
|
const ink = new Dict(xref);
|
||||||
ink.set("Type", Name.get("Annot"));
|
ink.set("Type", Name.get("Annot"));
|
||||||
ink.set("Subtype", Name.get("Ink"));
|
ink.set("Subtype", Name.get("Ink"));
|
||||||
@ -3643,6 +3656,19 @@ class InkAnnotation extends MarkupAnnotation {
|
|||||||
ink.set("Border", [0, 0, 0]);
|
ink.set("Border", [0, 0, 0]);
|
||||||
ink.set("Rotate", 0);
|
ink.set("Rotate", 0);
|
||||||
|
|
||||||
|
const n = new Dict(xref);
|
||||||
|
ink.set("AP", n);
|
||||||
|
|
||||||
|
if (apRef) {
|
||||||
|
n.set("N", apRef);
|
||||||
|
} else {
|
||||||
|
n.set("N", ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createNewAppearanceStream(annotation, xref) {
|
||||||
const [x1, y1, x2, y2] = annotation.rect;
|
const [x1, y1, x2, y2] = annotation.rect;
|
||||||
const w = x2 - x1;
|
const w = x2 - x1;
|
||||||
const h = y2 - y1;
|
const h = y2 - y1;
|
||||||
@ -3679,18 +3705,29 @@ class InkAnnotation extends MarkupAnnotation {
|
|||||||
const ap = new StringStream(appearance);
|
const ap = new StringStream(appearance);
|
||||||
ap.dict = appearanceStreamDict;
|
ap.dict = appearanceStreamDict;
|
||||||
|
|
||||||
buffer.length = 0;
|
return ap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async createNewAnnotation(
|
||||||
|
xref,
|
||||||
|
evaluator,
|
||||||
|
task,
|
||||||
|
annotation,
|
||||||
|
results,
|
||||||
|
others
|
||||||
|
) {
|
||||||
|
const inkRef = xref.getNewRef();
|
||||||
const apRef = xref.getNewRef();
|
const apRef = xref.getNewRef();
|
||||||
|
const ink = this.createInkDict(annotation, xref, { apRef });
|
||||||
|
const ap = this.createNewAppearanceStream(annotation, xref);
|
||||||
|
|
||||||
|
const buffer = [];
|
||||||
let transform = xref.encrypt
|
let transform = xref.encrypt
|
||||||
? xref.encrypt.createCipherTransform(apRef.num, apRef.gen)
|
? xref.encrypt.createCipherTransform(apRef.num, apRef.gen)
|
||||||
: null;
|
: null;
|
||||||
writeObject(apRef, ap, buffer, transform);
|
writeObject(apRef, ap, buffer, transform);
|
||||||
others.push({ ref: apRef, data: buffer.join("") });
|
others.push({ ref: apRef, data: buffer.join("") });
|
||||||
|
|
||||||
const n = new Dict(xref);
|
|
||||||
n.set("N", apRef);
|
|
||||||
ink.set("AP", n);
|
|
||||||
|
|
||||||
buffer.length = 0;
|
buffer.length = 0;
|
||||||
transform = xref.encrypt
|
transform = xref.encrypt
|
||||||
? xref.encrypt.createCipherTransform(inkRef.num, inkRef.gen)
|
? xref.encrypt.createCipherTransform(inkRef.num, inkRef.gen)
|
||||||
@ -3699,6 +3736,16 @@ class InkAnnotation extends MarkupAnnotation {
|
|||||||
|
|
||||||
results.push({ ref: inkRef, data: buffer.join("") });
|
results.push({ ref: inkRef, data: buffer.join("") });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async createNewPrintAnnotation(annotation, xref) {
|
||||||
|
const ap = this.createNewAppearanceStream(annotation, xref);
|
||||||
|
const ink = this.createInkDict(annotation, xref, { ap });
|
||||||
|
|
||||||
|
return new InkAnnotation({
|
||||||
|
dict: ink,
|
||||||
|
xref,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HighlightAnnotation extends MarkupAnnotation {
|
class HighlightAnnotation extends MarkupAnnotation {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
AnnotationEditorPrefix,
|
||||||
assert,
|
assert,
|
||||||
BaseException,
|
BaseException,
|
||||||
FontType,
|
FontType,
|
||||||
@ -548,6 +549,27 @@ function numberToString(value) {
|
|||||||
return value.toFixed(2);
|
return value.toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNewAnnotationsMap(annotationStorage) {
|
||||||
|
if (!annotationStorage) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const newAnnotationsByPage = new Map();
|
||||||
|
// The concept of page in a XFA is very different, so
|
||||||
|
// editing is just not implemented.
|
||||||
|
for (const [key, value] of annotationStorage) {
|
||||||
|
if (!key.startsWith(AnnotationEditorPrefix)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let annotations = newAnnotationsByPage.get(value.pageIndex);
|
||||||
|
if (!annotations) {
|
||||||
|
annotations = [];
|
||||||
|
newAnnotationsByPage.set(value.pageIndex, annotations);
|
||||||
|
}
|
||||||
|
annotations.push(value);
|
||||||
|
}
|
||||||
|
return newAnnotationsByPage.size > 0 ? newAnnotationsByPage : null;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
collectActions,
|
collectActions,
|
||||||
DocStats,
|
DocStats,
|
||||||
@ -556,6 +578,7 @@ export {
|
|||||||
getArrayLookupTableFactory,
|
getArrayLookupTableFactory,
|
||||||
getInheritableProperty,
|
getInheritableProperty,
|
||||||
getLookupTableFactory,
|
getLookupTableFactory,
|
||||||
|
getNewAnnotationsMap,
|
||||||
isWhiteSpace,
|
isWhiteSpace,
|
||||||
log2,
|
log2,
|
||||||
MissingDataException,
|
MissingDataException,
|
||||||
|
@ -33,6 +33,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
collectActions,
|
collectActions,
|
||||||
getInheritableProperty,
|
getInheritableProperty,
|
||||||
|
getNewAnnotationsMap,
|
||||||
isWhiteSpace,
|
isWhiteSpace,
|
||||||
MissingDataException,
|
MissingDataException,
|
||||||
validateCSSFont,
|
validateCSSFont,
|
||||||
@ -312,6 +313,8 @@ class Page {
|
|||||||
{ ref: this.ref, data: buffer.join("") },
|
{ ref: this.ref, data: buffer.join("") },
|
||||||
...newData.annotations
|
...newData.annotations
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.xref.resetNewRef();
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,6 +400,21 @@ class Page {
|
|||||||
options: this.evaluatorOptions,
|
options: this.evaluatorOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const newAnnotationsByPage = !this.xfaFactory
|
||||||
|
? getNewAnnotationsMap(annotationStorage)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
let newAnnotationsPromise = Promise.resolve(null);
|
||||||
|
if (newAnnotationsByPage) {
|
||||||
|
const newAnnotations = newAnnotationsByPage.get(this.pageIndex);
|
||||||
|
if (newAnnotations) {
|
||||||
|
newAnnotationsPromise = AnnotationFactory.printNewAnnotations(
|
||||||
|
partialEvaluator,
|
||||||
|
task,
|
||||||
|
newAnnotations
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
|
const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
|
||||||
const pageListPromise = dataPromises.then(([contentStream]) => {
|
const pageListPromise = dataPromises.then(([contentStream]) => {
|
||||||
const opList = new OperatorList(intent, sink);
|
const opList = new OperatorList(intent, sink);
|
||||||
@ -424,58 +442,63 @@ class Page {
|
|||||||
|
|
||||||
// Fetch the page's annotations and add their operator lists to the
|
// Fetch the page's annotations and add their operator lists to the
|
||||||
// page's operator list to render them.
|
// page's operator list to render them.
|
||||||
return Promise.all([pageListPromise, this._parsedAnnotations]).then(
|
return Promise.all([
|
||||||
function ([pageOpList, annotations]) {
|
pageListPromise,
|
||||||
if (
|
this._parsedAnnotations,
|
||||||
annotations.length === 0 ||
|
newAnnotationsPromise,
|
||||||
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
|
]).then(function ([pageOpList, annotations, newAnnotations]) {
|
||||||
) {
|
if (newAnnotations) {
|
||||||
pageOpList.flush(true);
|
annotations = annotations.concat(newAnnotations);
|
||||||
return { length: pageOpList.totalLength };
|
|
||||||
}
|
|
||||||
const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),
|
|
||||||
intentAny = !!(intent & RenderingIntentFlag.ANY),
|
|
||||||
intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
|
|
||||||
intentPrint = !!(intent & RenderingIntentFlag.PRINT);
|
|
||||||
|
|
||||||
// Collect the operator list promises for the annotations. Each promise
|
|
||||||
// is resolved with the complete operator list for a single annotation.
|
|
||||||
const opListPromises = [];
|
|
||||||
for (const annotation of annotations) {
|
|
||||||
if (
|
|
||||||
intentAny ||
|
|
||||||
(intentDisplay && annotation.mustBeViewed(annotationStorage)) ||
|
|
||||||
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
|
||||||
) {
|
|
||||||
opListPromises.push(
|
|
||||||
annotation
|
|
||||||
.getOperatorList(
|
|
||||||
partialEvaluator,
|
|
||||||
task,
|
|
||||||
intent,
|
|
||||||
renderForms,
|
|
||||||
annotationStorage
|
|
||||||
)
|
|
||||||
.catch(function (reason) {
|
|
||||||
warn(
|
|
||||||
"getOperatorList - ignoring annotation data during " +
|
|
||||||
`"${task.name}" task: "${reason}".`
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(opListPromises).then(function (opLists) {
|
|
||||||
for (const opList of opLists) {
|
|
||||||
pageOpList.addOpList(opList);
|
|
||||||
}
|
|
||||||
pageOpList.flush(true);
|
|
||||||
return { length: pageOpList.totalLength };
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
);
|
if (
|
||||||
|
annotations.length === 0 ||
|
||||||
|
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
|
||||||
|
) {
|
||||||
|
pageOpList.flush(true);
|
||||||
|
return { length: pageOpList.totalLength };
|
||||||
|
}
|
||||||
|
const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),
|
||||||
|
intentAny = !!(intent & RenderingIntentFlag.ANY),
|
||||||
|
intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
|
||||||
|
intentPrint = !!(intent & RenderingIntentFlag.PRINT);
|
||||||
|
|
||||||
|
// Collect the operator list promises for the annotations. Each promise
|
||||||
|
// is resolved with the complete operator list for a single annotation.
|
||||||
|
const opListPromises = [];
|
||||||
|
for (const annotation of annotations) {
|
||||||
|
if (
|
||||||
|
intentAny ||
|
||||||
|
(intentDisplay && annotation.mustBeViewed(annotationStorage)) ||
|
||||||
|
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
||||||
|
) {
|
||||||
|
opListPromises.push(
|
||||||
|
annotation
|
||||||
|
.getOperatorList(
|
||||||
|
partialEvaluator,
|
||||||
|
task,
|
||||||
|
intent,
|
||||||
|
renderForms,
|
||||||
|
annotationStorage
|
||||||
|
)
|
||||||
|
.catch(function (reason) {
|
||||||
|
warn(
|
||||||
|
"getOperatorList - ignoring annotation data during " +
|
||||||
|
`"${task.name}" task: "${reason}".`
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(opListPromises).then(function (opLists) {
|
||||||
|
for (const opList of opLists) {
|
||||||
|
pageOpList.addOpList(opList);
|
||||||
|
}
|
||||||
|
pageOpList.flush(true);
|
||||||
|
return { length: pageOpList.totalLength };
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
extractTextContent({
|
extractTextContent({
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AbortException,
|
AbortException,
|
||||||
AnnotationEditorPrefix,
|
|
||||||
arrayByteLength,
|
arrayByteLength,
|
||||||
arraysToBytes,
|
arraysToBytes,
|
||||||
createPromiseCapability,
|
createPromiseCapability,
|
||||||
@ -33,13 +32,13 @@ import {
|
|||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { Dict, Ref } from "./primitives.js";
|
import { Dict, Ref } from "./primitives.js";
|
||||||
|
import { getNewAnnotationsMap, XRefParseException } from "./core_utils.js";
|
||||||
import { LocalPdfManager, NetworkPdfManager } from "./pdf_manager.js";
|
import { LocalPdfManager, NetworkPdfManager } from "./pdf_manager.js";
|
||||||
import { clearGlobalCaches } from "./cleanup_helper.js";
|
import { clearGlobalCaches } from "./cleanup_helper.js";
|
||||||
import { incrementalUpdate } from "./writer.js";
|
import { incrementalUpdate } from "./writer.js";
|
||||||
import { isNodeJS } from "../shared/is_node.js";
|
import { isNodeJS } from "../shared/is_node.js";
|
||||||
import { MessageHandler } from "../shared/message_handler.js";
|
import { MessageHandler } from "../shared/message_handler.js";
|
||||||
import { PDFWorkerStream } from "./worker_stream.js";
|
import { PDFWorkerStream } from "./worker_stream.js";
|
||||||
import { XRefParseException } from "./core_utils.js";
|
|
||||||
|
|
||||||
class WorkerTask {
|
class WorkerTask {
|
||||||
constructor(name) {
|
constructor(name) {
|
||||||
@ -558,22 +557,9 @@ class WorkerMessageHandler {
|
|||||||
function ({ isPureXfa, numPages, annotationStorage, filename }) {
|
function ({ isPureXfa, numPages, annotationStorage, filename }) {
|
||||||
pdfManager.requestLoadedStream();
|
pdfManager.requestLoadedStream();
|
||||||
|
|
||||||
const newAnnotationsByPage = new Map();
|
const newAnnotationsByPage = !isPureXfa
|
||||||
if (!isPureXfa) {
|
? getNewAnnotationsMap(annotationStorage)
|
||||||
// The concept of page in a XFA is very different, so
|
: null;
|
||||||
// editing is just not implemented.
|
|
||||||
for (const [key, value] of annotationStorage) {
|
|
||||||
if (!key.startsWith(AnnotationEditorPrefix)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let annotations = newAnnotationsByPage.get(value.pageIndex);
|
|
||||||
if (!annotations) {
|
|
||||||
annotations = [];
|
|
||||||
newAnnotationsByPage.set(value.pageIndex, annotations);
|
|
||||||
}
|
|
||||||
annotations.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const promises = [
|
const promises = [
|
||||||
pdfManager.onLoadedStream(),
|
pdfManager.onLoadedStream(),
|
||||||
@ -583,17 +569,19 @@ class WorkerMessageHandler {
|
|||||||
pdfManager.ensureDoc("startXRef"),
|
pdfManager.ensureDoc("startXRef"),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const [pageIndex, annotations] of newAnnotationsByPage) {
|
if (newAnnotationsByPage) {
|
||||||
promises.push(
|
for (const [pageIndex, annotations] of newAnnotationsByPage) {
|
||||||
pdfManager.getPage(pageIndex).then(page => {
|
promises.push(
|
||||||
const task = new WorkerTask(`Save (editor): page ${pageIndex}`);
|
pdfManager.getPage(pageIndex).then(page => {
|
||||||
return page
|
const task = new WorkerTask(`Save (editor): page ${pageIndex}`);
|
||||||
.saveNewAnnotations(handler, task, annotations)
|
return page
|
||||||
.finally(function () {
|
.saveNewAnnotations(handler, task, annotations)
|
||||||
finishWorkerTask(task);
|
.finally(function () {
|
||||||
});
|
finishWorkerTask(task);
|
||||||
})
|
});
|
||||||
);
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPureXfa) {
|
if (isPureXfa) {
|
||||||
|
@ -6622,5 +6622,49 @@
|
|||||||
"rotation": 270
|
"rotation": 270
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "tracemonkey-editor",
|
||||||
|
"file": "pdfs/tracemonkey.pdf",
|
||||||
|
"md5": "9a192d8b1a7dc652a19835f6f08098bd",
|
||||||
|
"rounds": 1,
|
||||||
|
"lastPage": 1,
|
||||||
|
"type": "eq",
|
||||||
|
"print": true,
|
||||||
|
"annotationStorage": {
|
||||||
|
"pdfjs_internal_editor_0": {
|
||||||
|
"annotationType": 3,
|
||||||
|
"color": [0, 0, 0],
|
||||||
|
"fontSize": 10,
|
||||||
|
"value": "Hello World",
|
||||||
|
"pageIndex": 0,
|
||||||
|
"rect": [67.5, 543, 119, 556.5],
|
||||||
|
"orderIndex": 0
|
||||||
|
},
|
||||||
|
"pdfjs_internal_editor_1": {
|
||||||
|
"annotationType": 15,
|
||||||
|
"color": [255, 0, 0],
|
||||||
|
"thickness": 3,
|
||||||
|
"paths": [{
|
||||||
|
"bezier": [
|
||||||
|
1.5, 25.727771084724367, 2.8040804485100495, 27.031851533234402,
|
||||||
|
5.396811581133676, 23.25556095123241, 6, 22.727771084724367,
|
||||||
|
10.45407020558315, 18.830459654839103, 15.981183968598401,
|
||||||
|
16.364531104350363, 21, 13.227771084724367, 25.88795894206055,
|
||||||
|
10.172796745936523, 37.988543516372076, 5.739227568352277, 42,
|
||||||
|
1.7277710847243668
|
||||||
|
],
|
||||||
|
"points": [
|
||||||
|
1.5, 25.727771084724367, 5.225791198862495, 23.602568747729173,
|
||||||
|
4.012834511116397, 24.914722452856147, 6, 22.727771084724367, 21,
|
||||||
|
13.227771084724367, 37.71378602219673, 4.78737352236285,
|
||||||
|
31.828688421912233, 7.836451889039392, 42, 1.7277710847243668
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
"pageIndex": 0,
|
||||||
|
"rect": [71.5, 534.5, 115, 562],
|
||||||
|
"orderIndex": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -4186,6 +4186,58 @@ describe("annotation", function () {
|
|||||||
"endobj\n"
|
"endobj\n"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should render an added Ink annotation for printing", async function () {
|
||||||
|
partialEvaluator.xref = new XRefMock();
|
||||||
|
const task = new WorkerTask("test Ink printing");
|
||||||
|
const inkAnnotation = (
|
||||||
|
await AnnotationFactory.printNewAnnotations(partialEvaluator, task, [
|
||||||
|
{
|
||||||
|
annotationType: AnnotationEditorType.INK,
|
||||||
|
rect: [12, 34, 56, 78],
|
||||||
|
thickness: 1,
|
||||||
|
color: [0, 0, 0],
|
||||||
|
paths: [
|
||||||
|
{
|
||||||
|
bezier: [1, 2, 3, 4, 5, 6, 7, 8],
|
||||||
|
// Useless in the printing case.
|
||||||
|
points: [1, 2, 3, 4, 5, 6, 7, 8],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
const operatorList = await inkAnnotation.getOperatorList(
|
||||||
|
partialEvaluator,
|
||||||
|
task,
|
||||||
|
RenderingIntentFlag.PRINT,
|
||||||
|
false,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(operatorList.argsArray.length).toEqual(6);
|
||||||
|
expect(operatorList.fnArray).toEqual([
|
||||||
|
OPS.beginAnnotation,
|
||||||
|
OPS.setLineWidth,
|
||||||
|
OPS.setStrokeRGBColor,
|
||||||
|
OPS.constructPath,
|
||||||
|
OPS.stroke,
|
||||||
|
OPS.endAnnotation,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Linewidth.
|
||||||
|
expect(operatorList.argsArray[1]).toEqual([1]);
|
||||||
|
// Color.
|
||||||
|
expect(operatorList.argsArray[2]).toEqual(
|
||||||
|
new Uint8ClampedArray([0, 0, 0])
|
||||||
|
);
|
||||||
|
// Path.
|
||||||
|
expect(operatorList.argsArray[3][0]).toEqual([OPS.moveTo, OPS.curveTo]);
|
||||||
|
expect(operatorList.argsArray[3][1]).toEqual([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
|
// Min-max.
|
||||||
|
expect(operatorList.argsArray[3][2]).toEqual([1, 1, 2, 2]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("HightlightAnnotation", function () {
|
describe("HightlightAnnotation", function () {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user