Merge pull request #17531 from calixteman/editor_free_highlight_print_save
[Editor] Add support for printing/saving free highlight annotations
This commit is contained in:
commit
f6c4b29aa2
@ -355,13 +355,19 @@ class AnnotationFactory {
|
||||
);
|
||||
break;
|
||||
case AnnotationEditorType.HIGHLIGHT:
|
||||
promises.push(
|
||||
HighlightAnnotation.createNewAnnotation(
|
||||
xref,
|
||||
annotation,
|
||||
dependencies
|
||||
)
|
||||
);
|
||||
if (annotation.quadPoints) {
|
||||
promises.push(
|
||||
HighlightAnnotation.createNewAnnotation(
|
||||
xref,
|
||||
annotation,
|
||||
dependencies
|
||||
)
|
||||
);
|
||||
} else {
|
||||
promises.push(
|
||||
InkAnnotation.createNewAnnotation(xref, annotation, dependencies)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case AnnotationEditorType.INK:
|
||||
promises.push(
|
||||
@ -439,16 +445,29 @@ class AnnotationFactory {
|
||||
);
|
||||
break;
|
||||
case AnnotationEditorType.HIGHLIGHT:
|
||||
promises.push(
|
||||
HighlightAnnotation.createNewPrintAnnotation(
|
||||
annotationGlobals,
|
||||
xref,
|
||||
annotation,
|
||||
{
|
||||
evaluatorOptions: options,
|
||||
}
|
||||
)
|
||||
);
|
||||
if (annotation.quadPoints) {
|
||||
promises.push(
|
||||
HighlightAnnotation.createNewPrintAnnotation(
|
||||
annotationGlobals,
|
||||
xref,
|
||||
annotation,
|
||||
{
|
||||
evaluatorOptions: options,
|
||||
}
|
||||
)
|
||||
);
|
||||
} else {
|
||||
promises.push(
|
||||
InkAnnotation.createNewPrintAnnotation(
|
||||
annotationGlobals,
|
||||
xref,
|
||||
annotation,
|
||||
{
|
||||
evaluatorOptions: options,
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case AnnotationEditorType.INK:
|
||||
promises.push(
|
||||
@ -4340,19 +4359,25 @@ class InkAnnotation extends MarkupAnnotation {
|
||||
}
|
||||
|
||||
static createNewDict(annotation, xref, { apRef, ap }) {
|
||||
const { color, opacity, paths, rect, rotation, thickness } = annotation;
|
||||
const { color, opacity, paths, outlines, rect, rotation, thickness } =
|
||||
annotation;
|
||||
const ink = new Dict(xref);
|
||||
ink.set("Type", Name.get("Annot"));
|
||||
ink.set("Subtype", Name.get("Ink"));
|
||||
ink.set("CreationDate", `D:${getModificationDate()}`);
|
||||
ink.set("Rect", rect);
|
||||
ink.set(
|
||||
"InkList",
|
||||
paths.map(p => p.points)
|
||||
);
|
||||
ink.set("InkList", outlines?.points || paths.map(p => p.points));
|
||||
ink.set("F", 4);
|
||||
ink.set("Rotate", rotation);
|
||||
|
||||
if (outlines) {
|
||||
// Free highlight.
|
||||
// There's nothing about this in the spec, but it's used when highlighting
|
||||
// in Edge's viewer. Acrobat takes into account this parameter to indicate
|
||||
// that the Ink is used for highlighting.
|
||||
ink.set("IT", Name.get("InkHighlight"));
|
||||
}
|
||||
|
||||
// Line thickness.
|
||||
const bs = new Dict(xref);
|
||||
ink.set("BS", bs);
|
||||
@ -4380,6 +4405,13 @@ class InkAnnotation extends MarkupAnnotation {
|
||||
}
|
||||
|
||||
static async createNewAppearanceStream(annotation, xref, params) {
|
||||
if (annotation.outlines) {
|
||||
return this.createNewAppearanceStreamForHighlight(
|
||||
annotation,
|
||||
xref,
|
||||
params
|
||||
);
|
||||
}
|
||||
const { color, rect, paths, thickness, opacity } = annotation;
|
||||
|
||||
const appearanceBuffer = [
|
||||
@ -4438,6 +4470,65 @@ class InkAnnotation extends MarkupAnnotation {
|
||||
|
||||
return ap;
|
||||
}
|
||||
|
||||
static async createNewAppearanceStreamForHighlight(annotation, xref, params) {
|
||||
const {
|
||||
color,
|
||||
rect,
|
||||
outlines: { outline },
|
||||
opacity,
|
||||
} = annotation;
|
||||
const appearanceBuffer = [
|
||||
`${getPdfColor(color, /* isFill */ true)}`,
|
||||
"/R0 gs",
|
||||
];
|
||||
|
||||
appearanceBuffer.push(
|
||||
`${numberToString(outline[4])} ${numberToString(outline[5])} m`
|
||||
);
|
||||
for (let i = 6, ii = outline.length; i < ii; i += 6) {
|
||||
if (isNaN(outline[i]) || outline[i] === null) {
|
||||
appearanceBuffer.push(
|
||||
`${numberToString(outline[i + 4])} ${numberToString(
|
||||
outline[i + 5]
|
||||
)} l`
|
||||
);
|
||||
} else {
|
||||
const curve = outline
|
||||
.slice(i, i + 6)
|
||||
.map(numberToString)
|
||||
.join(" ");
|
||||
appearanceBuffer.push(`${curve} c`);
|
||||
}
|
||||
}
|
||||
appearanceBuffer.push("h f");
|
||||
const appearance = appearanceBuffer.join("\n");
|
||||
|
||||
const appearanceStreamDict = new Dict(xref);
|
||||
appearanceStreamDict.set("FormType", 1);
|
||||
appearanceStreamDict.set("Subtype", Name.get("Form"));
|
||||
appearanceStreamDict.set("Type", Name.get("XObject"));
|
||||
appearanceStreamDict.set("BBox", rect);
|
||||
appearanceStreamDict.set("Length", appearance.length);
|
||||
|
||||
const resources = new Dict(xref);
|
||||
const extGState = new Dict(xref);
|
||||
resources.set("ExtGState", extGState);
|
||||
appearanceStreamDict.set("Resources", resources);
|
||||
const r0 = new Dict(xref);
|
||||
extGState.set("R0", r0);
|
||||
r0.set("BM", Name.get("Multiply"));
|
||||
|
||||
if (opacity !== 1) {
|
||||
r0.set("ca", opacity);
|
||||
r0.set("Type", Name.get("ExtGState"));
|
||||
}
|
||||
|
||||
const ap = new StringStream(appearance);
|
||||
ap.dict = appearanceStreamDict;
|
||||
|
||||
return ap;
|
||||
}
|
||||
}
|
||||
|
||||
class HighlightAnnotation extends MarkupAnnotation {
|
||||
|
@ -32,7 +32,7 @@ async function writeObject(ref, obj, buffer, { encrypt = null }) {
|
||||
await writeDict(obj, buffer, transform);
|
||||
} else if (obj instanceof BaseStream) {
|
||||
await writeStream(obj, buffer, transform);
|
||||
} else if (Array.isArray(obj)) {
|
||||
} else if (Array.isArray(obj) || ArrayBuffer.isView(obj)) {
|
||||
await writeArray(obj, buffer, transform);
|
||||
}
|
||||
buffer.push("\nendobj\n");
|
||||
@ -132,7 +132,7 @@ async function writeValue(value, buffer, transform) {
|
||||
buffer.push(`/${escapePDFName(value.name)}`);
|
||||
} else if (value instanceof Ref) {
|
||||
buffer.push(`${value.num} ${value.gen} R`);
|
||||
} else if (Array.isArray(value)) {
|
||||
} else if (Array.isArray(value) || ArrayBuffer.isView(value)) {
|
||||
await writeArray(value, buffer, transform);
|
||||
} else if (typeof value === "string") {
|
||||
if (transform) {
|
||||
|
@ -597,6 +597,7 @@ class HighlightEditor extends AnnotationEditor {
|
||||
annotationType: AnnotationEditorType.HIGHLIGHT,
|
||||
color,
|
||||
opacity: this.#opacity,
|
||||
thickness: 2 * HighlightEditor._defaultThickness,
|
||||
quadPoints: this.#serializeBoxes(rect),
|
||||
outlines: this.#serializeOutlines(rect),
|
||||
pageIndex: this.pageIndex,
|
||||
|
@ -596,6 +596,12 @@ class FreeOutliner {
|
||||
const lastBottom = last.subarray(16, 18);
|
||||
const [layerX, layerY, layerWidth, layerHeight] = this.#box;
|
||||
|
||||
const points = new Float64Array(this.#points?.length ?? 0);
|
||||
for (let i = 0, ii = points.length; i < ii; i += 2) {
|
||||
points[i] = (this.#points[i] - layerX) / layerWidth;
|
||||
points[i + 1] = (this.#points[i + 1] - layerY) / layerHeight;
|
||||
}
|
||||
|
||||
if (isNaN(last[6]) && !this.isEmpty()) {
|
||||
// We've only two points.
|
||||
const outline = new Float64Array(24);
|
||||
@ -628,7 +634,12 @@ class FreeOutliner {
|
||||
],
|
||||
0
|
||||
);
|
||||
return new FreeHighlightOutline(outline, this.#innerMargin, isLTR);
|
||||
return new FreeHighlightOutline(
|
||||
outline,
|
||||
points,
|
||||
this.#innerMargin,
|
||||
isLTR
|
||||
);
|
||||
}
|
||||
|
||||
const outline = new Float64Array(
|
||||
@ -675,7 +686,7 @@ class FreeOutliner {
|
||||
}
|
||||
}
|
||||
outline.set([NaN, NaN, NaN, NaN, bottom[4], bottom[5]], N);
|
||||
return new FreeHighlightOutline(outline, this.#innerMargin, isLTR);
|
||||
return new FreeHighlightOutline(outline, points, this.#innerMargin, isLTR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,11 +695,14 @@ class FreeHighlightOutline extends Outline {
|
||||
|
||||
#innerMargin;
|
||||
|
||||
#points;
|
||||
|
||||
#outline;
|
||||
|
||||
constructor(outline, innerMargin, isLTR) {
|
||||
constructor(outline, points, innerMargin, isLTR) {
|
||||
super();
|
||||
this.#outline = outline;
|
||||
this.#points = points;
|
||||
this.#innerMargin = innerMargin;
|
||||
this.#computeMinMax(isLTR);
|
||||
|
||||
@ -697,6 +711,10 @@ class FreeHighlightOutline extends Outline {
|
||||
outline[i] = (outline[i] - x) / width;
|
||||
outline[i + 1] = (outline[i + 1] - y) / height;
|
||||
}
|
||||
for (let i = 0, ii = points.length; i < ii; i += 2) {
|
||||
points[i] = (points[i] - x) / width;
|
||||
points[i + 1] = (points[i + 1] - y) / height;
|
||||
}
|
||||
}
|
||||
|
||||
toSVGPath() {
|
||||
@ -717,36 +735,53 @@ class FreeHighlightOutline extends Outline {
|
||||
}
|
||||
|
||||
serialize([blX, blY, trX, trY], rotation) {
|
||||
const src = this.#outline;
|
||||
const outline = new Float64Array(src.length);
|
||||
const width = trX - blX;
|
||||
const height = trY - blY;
|
||||
let outline;
|
||||
let points;
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
for (let i = 0, ii = src.length; i < ii; i += 2) {
|
||||
outline[i] = blX + src[i] * width;
|
||||
outline[i + 1] = trY - src[i + 1] * height;
|
||||
}
|
||||
outline = this.#rescale(this.#outline, blX, trY, width, -height);
|
||||
points = this.#rescale(this.#points, blX, trY, width, -height);
|
||||
break;
|
||||
case 90:
|
||||
for (let i = 0, ii = src.length; i < ii; i += 2) {
|
||||
outline[i] = blX + src[i + 1] * width;
|
||||
outline[i + 1] = blY + src[i] * height;
|
||||
}
|
||||
outline = this.#rescaleAndSwap(this.#outline, blX, blY, width, height);
|
||||
points = this.#rescaleAndSwap(this.#points, blX, blY, width, height);
|
||||
break;
|
||||
case 180:
|
||||
for (let i = 0, ii = src.length; i < ii; i += 2) {
|
||||
outline[i] = trX - src[i] * width;
|
||||
outline[i + 1] = blY + src[i + 1] * height;
|
||||
}
|
||||
outline = this.#rescale(this.#outline, trX, blY, -width, height);
|
||||
points = this.#rescale(this.#points, trX, blY, -width, height);
|
||||
break;
|
||||
case 270:
|
||||
for (let i = 0, ii = src.length; i < ii; i += 2) {
|
||||
outline[i] = trX - src[i + 1] * width;
|
||||
outline[i + 1] = trY - src[i] * height;
|
||||
}
|
||||
outline = this.#rescaleAndSwap(
|
||||
this.#outline,
|
||||
trX,
|
||||
trY,
|
||||
-width,
|
||||
-height
|
||||
);
|
||||
points = this.#rescaleAndSwap(this.#points, trX, trY, -width, -height);
|
||||
break;
|
||||
}
|
||||
return outline;
|
||||
return { outline: Array.from(outline), points: [Array.from(points)] };
|
||||
}
|
||||
|
||||
#rescale(src, tx, ty, sx, sy) {
|
||||
const dest = new Float64Array(src.length);
|
||||
for (let i = 0, ii = src.length; i < ii; i += 2) {
|
||||
dest[i] = tx + src[i] * sx;
|
||||
dest[i + 1] = ty + src[i + 1] * sy;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
#rescaleAndSwap(src, tx, ty, sx, sy) {
|
||||
const dest = new Float64Array(src.length);
|
||||
for (let i = 0, ii = src.length; i < ii; i += 2) {
|
||||
dest[i] = tx + src[i + 1] * sx;
|
||||
dest[i + 1] = ty + src[i] * sy;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
#computeMinMax(isLTR) {
|
||||
|
@ -9324,5 +9324,324 @@
|
||||
"structTreeParentId": null
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tracemonkey-free-highlights",
|
||||
"file": "pdfs/tracemonkey.pdf",
|
||||
"md5": "9a192d8b1a7dc652a19835f6f08098bd",
|
||||
"rounds": 1,
|
||||
"lastPage": 1,
|
||||
"type": "eq",
|
||||
"print": true,
|
||||
"annotationStorage": {
|
||||
"pdfjs_internal_editor_0": {
|
||||
"annotationType": 9,
|
||||
"color": [83, 255, 188],
|
||||
"opacity": 1,
|
||||
"thickness": 20,
|
||||
"quadPoints": null,
|
||||
"outlines": {
|
||||
"outline": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
74.55,
|
||||
697.13,
|
||||
78.51721472766205,
|
||||
696.5192209591247,
|
||||
79.29044208205713,
|
||||
696.4224516456007,
|
||||
80.05486887178773,
|
||||
696.3379903011609,
|
||||
80.81929566151834,
|
||||
696.253528956721,
|
||||
81.57617646110613,
|
||||
696.1784636392651,
|
||||
82.32551127055109,
|
||||
696.1127943487935,
|
||||
83.07484607999606,
|
||||
696.047125058322,
|
||||
83.81784340794434,
|
||||
695.9886636959667,
|
||||
84.55450325439585,
|
||||
695.9374102617279,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
85.65949302407317,
|
||||
695.8605301103697,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
87.03393143844572,
|
||||
715.8149755833261,
|
||||
85.48426194954816,
|
||||
715.9204201846449,
|
||||
84.87281761152917,
|
||||
715.9671985492615,
|
||||
84.26979673105028,
|
||||
716.0185774379673,
|
||||
83.66677585057136,
|
||||
716.0699563266733,
|
||||
83.07457849467843,
|
||||
716.1266344280523,
|
||||
82.4932046633715,
|
||||
716.1886117421047,
|
||||
81.9118308320646,
|
||||
716.2505890561571,
|
||||
81.34439691081282,
|
||||
716.3184503202297,
|
||||
80.7909028996162,
|
||||
716.3921955343225,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
77.95775603227756,
|
||||
716.8481332058944
|
||||
],
|
||||
"points": [
|
||||
[
|
||||
76.25849755587352, 706.9926836109859, 86.14596273693202,
|
||||
705.2879914026346, 88.1916451881855, 705.2879914026346,
|
||||
90.23732763943899, 705.2879914026346, 92.28301009069247,
|
||||
705.2879914026346, 94.32869254194594, 705.2879914026346
|
||||
]
|
||||
]
|
||||
},
|
||||
"pageIndex": 0,
|
||||
"rect": [
|
||||
73.94723907946947, 695.0685301103697, 87.64593143844571,
|
||||
717.6401332058945
|
||||
],
|
||||
"rotation": 0,
|
||||
"structTreeParentId": null
|
||||
},
|
||||
"pdfjs_internal_editor_1": {
|
||||
"annotationType": 9,
|
||||
"color": [128, 235, 255],
|
||||
"opacity": 1,
|
||||
"thickness": 20,
|
||||
"quadPoints": null,
|
||||
"outlines": {
|
||||
"outline": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
260.9547742578311,
|
||||
674.9666484352592,
|
||||
265.0119754286617,
|
||||
674.7200369564051,
|
||||
265.85057115055446,
|
||||
674.6816601253416,
|
||||
266.8029560253001,
|
||||
674.6436779453497,
|
||||
267.7553409000457,
|
||||
674.6056957653577,
|
||||
268.641418670916,
|
||||
674.586241754074,
|
||||
269.46118933791087,
|
||||
674.5853159114982,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
270.6908453384032,
|
||||
674.5839271476348,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
270.6417128415015,
|
||||
694.586095213411,
|
||||
269.2921378713866,
|
||||
694.5754310173227,
|
||||
268.590908898233,
|
||||
694.5902107638636,
|
||||
267.72828093997174,
|
||||
694.624035935381,
|
||||
266.8656529817105,
|
||||
694.6578611068985,
|
||||
266.117024794879,
|
||||
694.6914601264726,
|
||||
265.48239637947734,
|
||||
694.7248329941037,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
262.2852690081439,
|
||||
694.9245750690663
|
||||
],
|
||||
"points": [
|
||||
[
|
||||
261.6200216329875, 684.9456117521628, 271.8481748830951,
|
||||
684.263717601745, 273.8938055331166, 684.263717601745,
|
||||
276.6213130664787, 684.263717601745, 278.6669437165002,
|
||||
684.6046646769539
|
||||
]
|
||||
]
|
||||
},
|
||||
"pageIndex": 0,
|
||||
"rect": [
|
||||
260.342789755033, 673.7919070919245, 271.30282984120134,
|
||||
695.7165951247766
|
||||
],
|
||||
"rotation": 90,
|
||||
"structTreeParentId": null
|
||||
},
|
||||
"pdfjs_internal_editor_2": {
|
||||
"annotationType": 9,
|
||||
"color": [255, 203, 230],
|
||||
"opacity": 1,
|
||||
"thickness": 20,
|
||||
"quadPoints": null,
|
||||
"outlines": {
|
||||
"outline": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
350.1249530717911,
|
||||
692.6633944602168,
|
||||
345.38916289103776,
|
||||
693.0766494920856,
|
||||
344.5712435088917,
|
||||
693.1558187178291,
|
||||
343.92282969955727,
|
||||
693.2395419718531,
|
||||
343.2744158902228,
|
||||
693.3232652258769,
|
||||
342.6222941207318,
|
||||
693.408487931081,
|
||||
341.96646439108423,
|
||||
693.4952100874651,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
340.9827197966128,
|
||||
693.6252933220413,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
338.36438011302045,
|
||||
673.7956810233082,
|
||||
340.14908906785814,
|
||||
673.5603604426211,
|
||||
340.9899862433436,
|
||||
673.4556612067797,
|
||||
341.95789701237936,
|
||||
673.3403909673718,
|
||||
342.92580778141513,
|
||||
673.2251207279638,
|
||||
343.81937416539495,
|
||||
673.1375137282872,
|
||||
344.63859616431887,
|
||||
673.0775699683421,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
348.1346569560641,
|
||||
672.7609372902139
|
||||
],
|
||||
"points": [
|
||||
[
|
||||
349.12980501392764, 682.7121658752152, 338.9013927576602,
|
||||
683.734981200226, 336.1738161559889, 683.734981200226,
|
||||
333.7871866295265, 684.4168580835666, 331.74150417827303,
|
||||
684.7577965252368
|
||||
]
|
||||
]
|
||||
},
|
||||
"pageIndex": 0,
|
||||
"rect": [
|
||||
337.7523801130204, 671.9689372902138, 350.7369530717911,
|
||||
694.4172933220414
|
||||
],
|
||||
"rotation": 180,
|
||||
"structTreeParentId": null
|
||||
},
|
||||
"pdfjs_internal_editor_3": {
|
||||
"annotationType": 9,
|
||||
"color": [255, 79, 95],
|
||||
"opacity": 1,
|
||||
"thickness": 20,
|
||||
"quadPoints": null,
|
||||
"outlines": {
|
||||
"outline": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
534.1504350586464,
|
||||
715.0615382740357,
|
||||
530.2182783647162,
|
||||
715.0615382740357,
|
||||
529.5364014813756,
|
||||
715.0615382740357,
|
||||
528.8545245980351,
|
||||
715.0615382740357,
|
||||
528.1726477146946,
|
||||
715.0615382740357,
|
||||
527.4339477577424,
|
||||
715.0615382740357,
|
||||
526.6384247271785,
|
||||
715.0615382740357,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
525.4451401813326,
|
||||
715.0615382740357,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
525.4451401813326,
|
||||
695.0593098617794,
|
||||
527.4339477577424,
|
||||
695.0593098617794,
|
||||
528.1726477146946,
|
||||
695.0593098617794,
|
||||
528.8545245980351,
|
||||
695.0593098617794,
|
||||
529.5364014813756,
|
||||
695.0593098617794,
|
||||
530.2182783647162,
|
||||
695.0593098617794,
|
||||
530.9001552480566,
|
||||
695.0593098617794,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
534.1504350586464,
|
||||
695.0593098617794
|
||||
],
|
||||
"points": [
|
||||
[
|
||||
534.1504350586464, 705.0604240679075, 523.9222818085387,
|
||||
705.0604240679075, 521.8766511585172, 705.0604240679075,
|
||||
519.8310205084957, 705.0604240679075, 517.444451416804,
|
||||
705.0604240679075
|
||||
]
|
||||
]
|
||||
},
|
||||
"pageIndex": 0,
|
||||
"rect": [
|
||||
524.8331556785345, 694.2672898060691, 534.7624195614445,
|
||||
715.853558329746
|
||||
],
|
||||
"rotation": 270,
|
||||
"structTreeParentId": null
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -4708,6 +4708,125 @@ describe("annotation", function () {
|
||||
OPS.endAnnotation,
|
||||
]);
|
||||
});
|
||||
|
||||
it("should create a new free Highlight annotation", async function () {
|
||||
partialEvaluator.xref = new XRefMock();
|
||||
const task = new WorkerTask("test free Highlight creation");
|
||||
const data = await AnnotationFactory.saveNewAnnotations(
|
||||
partialEvaluator,
|
||||
task,
|
||||
[
|
||||
{
|
||||
annotationType: AnnotationEditorType.HIGHLIGHT,
|
||||
rect: [12, 34, 56, 78],
|
||||
rotation: 0,
|
||||
opacity: 1,
|
||||
color: [0, 0, 0],
|
||||
thickness: 3.14,
|
||||
quadPoints: null,
|
||||
outlines: {
|
||||
outline: Float64Array.from([
|
||||
NaN,
|
||||
NaN,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
NaN,
|
||||
NaN,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
]),
|
||||
points: [Float64Array.from([16, 17, 18, 19])],
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
const base = data.annotations[0].data.replace(/\(D:\d+\)/, "(date)");
|
||||
expect(base).toEqual(
|
||||
"1 0 obj\n" +
|
||||
"<< /Type /Annot /Subtype /Ink /CreationDate (date) /Rect [12 34 56 78] " +
|
||||
"/InkList [[16 17 18 19]] /F 4 /Rotate 0 /IT /InkHighlight /BS << /W 3.14>> " +
|
||||
"/C [0 0 0] /CA 1 /AP << /N 2 0 R>>>>\n" +
|
||||
"endobj\n"
|
||||
);
|
||||
|
||||
const appearance = data.dependencies[0].data;
|
||||
expect(appearance).toEqual(
|
||||
"2 0 obj\n" +
|
||||
"<< /FormType 1 /Subtype /Form /Type /XObject /BBox [12 34 56 78] " +
|
||||
"/Length 30 /Resources << /ExtGState << /R0 << /BM /Multiply>>>>>>>> " +
|
||||
"stream\n" +
|
||||
"0 g\n" +
|
||||
"/R0 gs\n" +
|
||||
"10 11 m\n" +
|
||||
"14 15 l\n" +
|
||||
"h f\n" +
|
||||
"endstream\n" +
|
||||
"endobj\n"
|
||||
);
|
||||
});
|
||||
|
||||
it("should render a new free Highlight annotation for printing", async function () {
|
||||
partialEvaluator.xref = new XRefMock();
|
||||
const task = new WorkerTask("test free Highlight printing");
|
||||
const highlightAnnotation = (
|
||||
await AnnotationFactory.printNewAnnotations(
|
||||
annotationGlobalsMock,
|
||||
partialEvaluator,
|
||||
task,
|
||||
[
|
||||
{
|
||||
annotationType: AnnotationEditorType.HIGHLIGHT,
|
||||
rect: [12, 34, 56, 78],
|
||||
rotation: 0,
|
||||
opacity: 0.5,
|
||||
color: [0, 255, 0],
|
||||
thickness: 3.14,
|
||||
quadPoints: null,
|
||||
outlines: {
|
||||
outline: Float64Array.from([
|
||||
NaN,
|
||||
NaN,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
NaN,
|
||||
NaN,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
]),
|
||||
points: [Float64Array.from([16, 17, 18, 19])],
|
||||
},
|
||||
},
|
||||
]
|
||||
)
|
||||
)[0];
|
||||
|
||||
const { opList } = await highlightAnnotation.getOperatorList(
|
||||
partialEvaluator,
|
||||
task,
|
||||
RenderingIntentFlag.PRINT,
|
||||
false,
|
||||
null
|
||||
);
|
||||
|
||||
expect(opList.argsArray.length).toEqual(6);
|
||||
expect(opList.fnArray).toEqual([
|
||||
OPS.beginAnnotation,
|
||||
OPS.setFillRGBColor,
|
||||
OPS.setGState,
|
||||
OPS.constructPath,
|
||||
OPS.fill,
|
||||
OPS.endAnnotation,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("UnderlineAnnotation", function () {
|
||||
|
Loading…
Reference in New Issue
Block a user