Skip to content

Commit

Permalink
Merge pull request #18805 from calixteman/update_stamp
Browse files Browse the repository at this point in the history
[Editor] Add the possibility to save an updated stamp annotation (bug 1921291)
  • Loading branch information
calixteman authored Oct 2, 2024
2 parents e25832c + c9050be commit 567df42
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 83 deletions.
78 changes: 44 additions & 34 deletions src/core/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,10 @@ class AnnotationFactory {
);
break;
case AnnotationEditorType.STAMP:
if (!isOffscreenCanvasSupported) {
break;
}
const image = await imagePromises.get(annotation.bitmapId);
if (image.imageStream) {
const image = isOffscreenCanvasSupported
? await imagePromises?.get(annotation.bitmapId)
: null;
if (image?.imageStream) {
const { imageStream, smaskStream } = image;
const buffer = [];
if (smaskStream) {
Expand Down Expand Up @@ -488,11 +487,10 @@ class AnnotationFactory {
);
break;
case AnnotationEditorType.STAMP:
if (!options.isOffscreenCanvasSupported) {
break;
}
const image = await imagePromises.get(annotation.bitmapId);
if (image.imageStream) {
const image = options.isOffscreenCanvasSupported
? await imagePromises?.get(annotation.bitmapId)
: null;
if (image?.imageStream) {
const { imageStream, smaskStream } = image;
if (smaskStream) {
imageStream.dict.set("SMask", smaskStream);
Expand Down Expand Up @@ -653,17 +651,6 @@ class Annotation {
const isLocked = !!(this.flags & AnnotationFlag.LOCKED);
const isContentLocked = !!(this.flags & AnnotationFlag.LOCKEDCONTENTS);

if (annotationGlobals.structTreeRoot) {
let structParent = dict.get("StructParent");
structParent =
Number.isInteger(structParent) && structParent >= 0 ? structParent : -1;

annotationGlobals.structTreeRoot.addAnnotationIdToPage(
params.pageRef,
structParent
);
}

// Expose public properties using a data object.
this.data = {
annotationFlags: this.flags,
Expand All @@ -682,8 +669,20 @@ class Annotation {
noRotate: !!(this.flags & AnnotationFlag.NOROTATE),
noHTML: isLocked && isContentLocked,
isEditable: false,
structParent: -1,
};

if (annotationGlobals.structTreeRoot) {
let structParent = dict.get("StructParent");
this.data.structParent = structParent =
Number.isInteger(structParent) && structParent >= 0 ? structParent : -1;

annotationGlobals.structTreeRoot.addAnnotationIdToPage(
params.pageRef,
structParent
);
}

if (params.collectFields) {
// Fields can act as container for other fields and have
// some actions even if no Annotation inherit from them.
Expand Down Expand Up @@ -1751,10 +1750,7 @@ class MarkupAnnotation extends Annotation {
}

static async createNewAnnotation(xref, annotation, dependencies, params) {
let oldAnnotation;
if (annotation.ref) {
oldAnnotation = (await xref.fetchIfRefAsync(annotation.ref)).clone();
} else {
if (!annotation.ref) {
annotation.ref = xref.getNewTemporaryRef();
}

Expand All @@ -1767,12 +1763,11 @@ class MarkupAnnotation extends Annotation {
const apRef = xref.getNewTemporaryRef();
annotationDict = this.createNewDict(annotation, xref, {
apRef,
oldAnnotation,
});
await writeObject(apRef, ap, buffer, xref);
dependencies.push({ ref: apRef, data: buffer.join("") });
} else {
annotationDict = this.createNewDict(annotation, xref, { oldAnnotation });
annotationDict = this.createNewDict(annotation, xref, {});
}
if (Number.isInteger(annotation.parentTreeId)) {
annotationDict.set("StructParent", annotation.parentTreeId);
Expand All @@ -1791,7 +1786,11 @@ class MarkupAnnotation extends Annotation {
params
) {
const ap = await this.createNewAppearanceStream(annotation, xref, params);
const annotationDict = this.createNewDict(annotation, xref, { ap });
const annotationDict = this.createNewDict(
annotation,
xref,
ap ? { ap } : {}
);

const newAnnotation = new this.prototype.constructor({
dict: annotationDict,
Expand Down Expand Up @@ -3904,8 +3903,9 @@ class FreeTextAnnotation extends MarkupAnnotation {
return this._hasAppearance;
}

static createNewDict(annotation, xref, { apRef, ap, oldAnnotation }) {
const { color, fontSize, rect, rotation, user, value } = annotation;
static createNewDict(annotation, xref, { apRef, ap }) {
const { color, fontSize, oldAnnotation, rect, rotation, user, value } =
annotation;
const freetext = oldAnnotation || new Dict(xref);
freetext.set("Type", Name.get("Annot"));
freetext.set("Subtype", Name.get("FreeText"));
Expand Down Expand Up @@ -4646,8 +4646,9 @@ class HighlightAnnotation extends MarkupAnnotation {
}
}

static createNewDict(annotation, xref, { apRef, ap, oldAnnotation }) {
const { color, opacity, rect, rotation, user, quadPoints } = annotation;
static createNewDict(annotation, xref, { apRef, ap }) {
const { color, oldAnnotation, opacity, rect, rotation, user, quadPoints } =
annotation;
const highlight = oldAnnotation || new Dict(xref);
highlight.set("Type", Name.get("Annot"));
highlight.set("Subtype", Name.get("Highlight"));
Expand Down Expand Up @@ -4943,10 +4944,14 @@ class StampAnnotation extends MarkupAnnotation {
}

static createNewDict(annotation, xref, { apRef, ap }) {
const { rect, rotation, user } = annotation;
const stamp = new Dict(xref);
const { oldAnnotation, rect, rotation, user } = annotation;
const stamp = oldAnnotation || new Dict(xref);
stamp.set("Type", Name.get("Annot"));
stamp.set("Subtype", Name.get("Stamp"));
stamp.set(
oldAnnotation ? "M" : "CreationDate",
`D:${getModificationDate()}`
);
stamp.set("CreationDate", `D:${getModificationDate()}`);
stamp.set("Rect", rect);
stamp.set("F", 4);
Expand All @@ -4972,6 +4977,11 @@ class StampAnnotation extends MarkupAnnotation {
}

static async createNewAppearanceStream(annotation, xref, params) {
if (annotation.oldAnnotation) {
// We'll use the AP we already have.
return null;
}

const { rotation } = annotation;
const { imageRef, width, height } = params.image;
const resources = new Dict(xref);
Expand Down
52 changes: 35 additions & 17 deletions src/core/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ class Page {
);
}

#replaceIdByRef(annotations, deletedAnnotations, existingAnnotations) {
async #replaceIdByRef(annotations, deletedAnnotations, existingAnnotations) {
const promises = [];
for (const annotation of annotations) {
if (annotation.id) {
const ref = Ref.fromString(annotation.id);
Expand All @@ -294,9 +295,22 @@ class Page {
}
existingAnnotations?.put(ref);
annotation.ref = ref;
promises.push(
this.xref.fetchAsync(ref).then(
obj => {
if (obj instanceof Dict) {
annotation.oldAnnotation = obj.clone();
}
},
() => {
warn(`Cannot fetch \`oldAnnotation\` for: ${ref}.`);
}
)
);
delete annotation.id;
}
}
await Promise.all(promises);
}

async saveNewAnnotations(handler, task, annotations, imagePromises) {
Expand All @@ -319,7 +333,11 @@ class Page {

const deletedAnnotations = new RefSetCache();
const existingAnnotations = new RefSet();
this.#replaceIdByRef(annotations, deletedAnnotations, existingAnnotations);
await this.#replaceIdByRef(
annotations,
deletedAnnotations,
existingAnnotations
);

const pageDict = this.pageDict;
const annotationsArray = this.annotations.filter(
Expand Down Expand Up @@ -489,23 +507,23 @@ class Page {
}

deletedAnnotations = new RefSet();
this.#replaceIdByRef(newAnnots, deletedAnnotations, null);

newAnnotationsPromise = annotationGlobalsPromise.then(
annotationGlobals => {
if (!annotationGlobals) {
return null;
}

return AnnotationFactory.printNewAnnotations(
annotationGlobals,
partialEvaluator,
task,
newAnnots,
imagePromises
);
newAnnotationsPromise = Promise.all([
annotationGlobalsPromise,
this.#replaceIdByRef(newAnnots, deletedAnnotations, null),
]).then(([annotationGlobals]) => {
if (!annotationGlobals) {
return null;
}
);

return AnnotationFactory.printNewAnnotations(
annotationGlobals,
partialEvaluator,
task,
newAnnots,
imagePromises
);
});
}

const pageListPromise = Promise.all([
Expand Down
8 changes: 6 additions & 2 deletions src/core/name_number_tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class NameOrNumberTree {
return map;
}

get(key) {
getRaw(key) {
if (!this.root) {
return null;
}
Expand Down Expand Up @@ -135,12 +135,16 @@ class NameOrNumberTree {
} else if (key > currentKey) {
l = m + 2;
} else {
return xref.fetchIfRef(entries[m + 1]);
return entries[m + 1];
}
}
}
return null;
}

get(key) {
return this.xref.fetchIfRef(this.getRaw(key));
}
}

class NameTree extends NameOrNumberTree {
Expand Down
Loading

0 comments on commit 567df42

Please sign in to comment.