mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-07-25 08:27:19 +02:00
Merge b8266a2ecf69ed7bf65675109e39f65b25c58efa into 5f4d923618df3c47f706e0c0f8215469240c8f1b
This commit is contained in:
commit
cc3f961da0
@ -45,6 +45,7 @@ import {
|
|||||||
getParentToUpdate,
|
getParentToUpdate,
|
||||||
getRotationMatrix,
|
getRotationMatrix,
|
||||||
isNumberArray,
|
isNumberArray,
|
||||||
|
lookupLineEnding,
|
||||||
lookupMatrix,
|
lookupMatrix,
|
||||||
lookupNormalRect,
|
lookupNormalRect,
|
||||||
lookupRect,
|
lookupRect,
|
||||||
@ -983,6 +984,18 @@ class Annotation {
|
|||||||
this.color = getRgbColor(color);
|
this.color = getRgbColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the line ending; should only be used with FreeText annotations.
|
||||||
|
* @param {Name} lineEnding - The line ending name.
|
||||||
|
*/
|
||||||
|
setLineEnding(lineEnding) {
|
||||||
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
|
||||||
|
throw new Error("Not implemented: setLineEnding");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lineEnding = lookupLineEnding(lineEnding, "None");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the line endings; should only be used with specific annotation types.
|
* Set the line endings; should only be used with specific annotation types.
|
||||||
* @param {Array} lineEndings - The line endings array.
|
* @param {Array} lineEndings - The line endings array.
|
||||||
@ -995,26 +1008,7 @@ class Annotation {
|
|||||||
|
|
||||||
if (Array.isArray(lineEndings) && lineEndings.length === 2) {
|
if (Array.isArray(lineEndings) && lineEndings.length === 2) {
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
const obj = lineEndings[i];
|
this.lineEndings[i] = lookupLineEnding(lineEndings[i], "None");
|
||||||
|
|
||||||
if (obj instanceof Name) {
|
|
||||||
switch (obj.name) {
|
|
||||||
case "None":
|
|
||||||
continue;
|
|
||||||
case "Square":
|
|
||||||
case "Circle":
|
|
||||||
case "Diamond":
|
|
||||||
case "OpenArrow":
|
|
||||||
case "ClosedArrow":
|
|
||||||
case "Butt":
|
|
||||||
case "ROpenArrow":
|
|
||||||
case "RClosedArrow":
|
|
||||||
case "Slash":
|
|
||||||
this.lineEndings[i] = obj.name;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
warn(`Ignoring invalid lineEnding: ${obj}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3880,11 +3874,23 @@ class FreeTextAnnotation extends MarkupAnnotation {
|
|||||||
// We want to be able to add mouse listeners to the annotation.
|
// We want to be able to add mouse listeners to the annotation.
|
||||||
this.data.noHTML = false;
|
this.data.noHTML = false;
|
||||||
|
|
||||||
const { evaluatorOptions, xref } = params;
|
const { evaluatorOptions, xref, dict } = params;
|
||||||
this.data.annotationType = AnnotationType.FREETEXT;
|
this.data.annotationType = AnnotationType.FREETEXT;
|
||||||
this.setDefaultAppearance(params);
|
this.setDefaultAppearance(params);
|
||||||
this._hasAppearance = !!this.appearance;
|
this._hasAppearance = !!this.appearance;
|
||||||
|
|
||||||
|
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
|
||||||
|
if (this.data.it === "FreeTextCallout") {
|
||||||
|
this.setLineEnding(dict.get("LE"));
|
||||||
|
this.data.lineEnding = this.lineEnding;
|
||||||
|
|
||||||
|
const calloutLine = dict.getArray("CL");
|
||||||
|
if (isNumberArray(calloutLine, 4) || isNumberArray(calloutLine, 6)) {
|
||||||
|
this.data.calloutLine = calloutLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this._hasAppearance) {
|
if (this._hasAppearance) {
|
||||||
const { fontColor, fontSize } = parseAppearanceStream(
|
const { fontColor, fontSize } = parseAppearanceStream(
|
||||||
this.appearance,
|
this.appearance,
|
||||||
@ -3932,8 +3938,17 @@ class FreeTextAnnotation extends MarkupAnnotation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static createNewDict(annotation, xref, { apRef, ap }) {
|
static createNewDict(annotation, xref, { apRef, ap }) {
|
||||||
const { color, fontSize, oldAnnotation, rect, rotation, user, value } =
|
const {
|
||||||
annotation;
|
calloutLine,
|
||||||
|
color,
|
||||||
|
fontSize,
|
||||||
|
lineEnding,
|
||||||
|
oldAnnotation,
|
||||||
|
rect,
|
||||||
|
rotation,
|
||||||
|
user,
|
||||||
|
value,
|
||||||
|
} = annotation;
|
||||||
const freetext = oldAnnotation || new Dict(xref);
|
const freetext = oldAnnotation || new Dict(xref);
|
||||||
freetext.set("Type", Name.get("Annot"));
|
freetext.set("Type", Name.get("Annot"));
|
||||||
freetext.set("Subtype", Name.get("FreeText"));
|
freetext.set("Subtype", Name.get("FreeText"));
|
||||||
@ -3953,6 +3968,15 @@ class FreeTextAnnotation extends MarkupAnnotation {
|
|||||||
freetext.set("Border", [0, 0, 0]);
|
freetext.set("Border", [0, 0, 0]);
|
||||||
freetext.set("Rotate", rotation);
|
freetext.set("Rotate", rotation);
|
||||||
|
|
||||||
|
if (calloutLine) {
|
||||||
|
freetext.set("IT", Name.get("FreeTextCallout"));
|
||||||
|
|
||||||
|
freetext.set("CL", calloutLine);
|
||||||
|
if (lineEnding) {
|
||||||
|
freetext.set("LE", Name.get(lineEnding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
freetext.set("T", stringToAsciiOrUTF16BE(user));
|
freetext.set("T", stringToAsciiOrUTF16BE(user));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import {
|
|||||||
Util,
|
Util,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { Dict, isName, Ref, RefSet } from "./primitives.js";
|
import { Dict, isName, Name, Ref, RefSet } from "./primitives.js";
|
||||||
import { BaseStream } from "./base_stream.js";
|
import { BaseStream } from "./base_stream.js";
|
||||||
|
|
||||||
const PDF_VERSION_REGEXP = /^[1-9]\.\d$/;
|
const PDF_VERSION_REGEXP = /^[1-9]\.\d$/;
|
||||||
@ -304,6 +304,27 @@ function lookupNormalRect(arr, fallback) {
|
|||||||
return isNumberArray(arr, 4) ? Util.normalizeRect(arr) : fallback;
|
return isNumberArray(arr, 4) ? Util.normalizeRect(arr) : fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the line ending style, or the fallback value if it's invalid.
|
||||||
|
function lookupLineEnding(value, fallback) {
|
||||||
|
if (value instanceof Name) {
|
||||||
|
switch (value.name) {
|
||||||
|
case "None":
|
||||||
|
case "Square":
|
||||||
|
case "Circle":
|
||||||
|
case "Diamond":
|
||||||
|
case "OpenArrow":
|
||||||
|
case "ClosedArrow":
|
||||||
|
case "Butt":
|
||||||
|
case "ROpenArrow":
|
||||||
|
case "RClosedArrow":
|
||||||
|
case "Slash":
|
||||||
|
return value.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AcroForm field names use an array like notation to refer to
|
* AcroForm field names use an array like notation to refer to
|
||||||
* repeated XFA elements e.g. foo.bar[nnn].
|
* repeated XFA elements e.g. foo.bar[nnn].
|
||||||
@ -727,6 +748,7 @@ export {
|
|||||||
isNumberArray,
|
isNumberArray,
|
||||||
isWhiteSpace,
|
isWhiteSpace,
|
||||||
log2,
|
log2,
|
||||||
|
lookupLineEnding,
|
||||||
lookupMatrix,
|
lookupMatrix,
|
||||||
lookupNormalRect,
|
lookupNormalRect,
|
||||||
lookupRect,
|
lookupRect,
|
||||||
|
|||||||
@ -4257,6 +4257,40 @@ describe("annotation", function () {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should create a new FreeTextCallout annotation", async () => {
|
||||||
|
const xref = (partialEvaluator.xref = new XRefMock());
|
||||||
|
const task = new WorkerTask("test FreeText creation");
|
||||||
|
const changes = new RefSetCache();
|
||||||
|
await AnnotationFactory.saveNewAnnotations(
|
||||||
|
partialEvaluator,
|
||||||
|
task,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
annotationType: AnnotationEditorType.FREETEXT,
|
||||||
|
rect: [12, 34, 56, 78],
|
||||||
|
rotation: 0,
|
||||||
|
fontSize: 10,
|
||||||
|
color: [0, 0, 0],
|
||||||
|
calloutLine: [0, 0, 10, 56, 12, 56],
|
||||||
|
lineEnding: "OpenArrow",
|
||||||
|
value: "Hello PDF.js World!",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
changes
|
||||||
|
);
|
||||||
|
const data = await writeChanges(changes, xref);
|
||||||
|
|
||||||
|
const base = data[1].data.replace(/\(D:\d+\)/, "(date)");
|
||||||
|
expect(base).toEqual(
|
||||||
|
"2 0 obj\n" +
|
||||||
|
"<< /Type /Annot /Subtype /FreeText /CreationDate (date) " +
|
||||||
|
"/Rect [12 34 56 78] /DA (/Helv 10 Tf 0 g) /Contents (Hello PDF.js World!) " +
|
||||||
|
"/F 4 /Border [0 0 0] /Rotate 0 /IT /FreeTextCallout /CL [0 0 10 56 12 56] /LE /OpenArrow /AP << /N 3 0 R>>>>\n" +
|
||||||
|
"endobj\n"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should render an added FreeText annotation for printing", async function () {
|
it("should render an added FreeText annotation for printing", async function () {
|
||||||
partialEvaluator.xref = new XRefMock();
|
partialEvaluator.xref = new XRefMock();
|
||||||
const task = new WorkerTask("test FreeText printing");
|
const task = new WorkerTask("test FreeText printing");
|
||||||
@ -4384,6 +4418,38 @@ describe("annotation", function () {
|
|||||||
"World !",
|
"World !",
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should parse callout line from a FreeTextCallout annotation", async function () {
|
||||||
|
partialEvaluator.xref = new XRefMock();
|
||||||
|
const task = new WorkerTask("test FreeTextCallout line parsing");
|
||||||
|
const freetextAnnotation = (
|
||||||
|
await AnnotationFactory.printNewAnnotations(
|
||||||
|
annotationGlobalsMock,
|
||||||
|
partialEvaluator,
|
||||||
|
task,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
annotationType: AnnotationEditorType.FREETEXT,
|
||||||
|
rect: [12, 34, 56, 78],
|
||||||
|
rotation: 0,
|
||||||
|
fontSize: 10,
|
||||||
|
color: [0, 0, 0],
|
||||||
|
calloutLine: [0, 0, 10, 56, 12, 56],
|
||||||
|
lineEnding: "OpenArrow",
|
||||||
|
value: "Hello PDF.js\nWorld !",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
expect(freetextAnnotation.data.it).toEqual("FreeTextCallout");
|
||||||
|
|
||||||
|
expect(freetextAnnotation.data.calloutLine).toEqual([
|
||||||
|
0, 0, 10, 56, 12, 56,
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(freetextAnnotation.data.lineEnding).toEqual("OpenArrow");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("InkAnnotation", function () {
|
describe("InkAnnotation", function () {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user