[Editor] Add support for printing/saving newly added Stamp annotations

In order to minimize the size the of a saved pdf, we generate only one
image and use a reference in each annotation using it.
When printing, it's slightly different since we have to render each page
independantly but we use the same image within a page.
This commit is contained in:
Calixte Denizet 2023-06-22 19:48:40 +02:00
parent ccb72073b0
commit 599b9498f2
9 changed files with 519 additions and 19 deletions

View file

@ -13,8 +13,8 @@
* limitations under the License.
*/
import { AnnotationFactory, PopupAnnotation } from "./annotation.js";
import {
AnnotationEditorPrefix,
assert,
FormatError,
info,
@ -30,6 +30,7 @@ import {
Util,
warn,
} from "../shared/util.js";
import { AnnotationFactory, PopupAnnotation } from "./annotation.js";
import {
collectActions,
getInheritableProperty,
@ -277,7 +278,7 @@ class Page {
}
}
async saveNewAnnotations(handler, task, annotations) {
async saveNewAnnotations(handler, task, annotations, imagePromises) {
if (this.xfaFactory) {
throw new Error("XFA: Cannot save new annotations.");
}
@ -306,7 +307,8 @@ class Page {
const newData = await AnnotationFactory.saveNewAnnotations(
partialEvaluator,
task,
annotations
annotations,
imagePromises
);
for (const { ref } of newData.annotations) {
@ -433,14 +435,52 @@ class Page {
let newAnnotationsPromise = Promise.resolve(null);
if (newAnnotationsByPage) {
let imagePromises;
const newAnnotations = newAnnotationsByPage.get(this.pageIndex);
if (newAnnotations) {
// An annotation can contain a reference to a bitmap, but this bitmap
// is defined in another annotation. So we need to find this annotation
// and generate the bitmap.
const missingBitmaps = new Set();
for (const { bitmapId, bitmap } of newAnnotations) {
if (bitmapId && !bitmap && !missingBitmaps.has(bitmapId)) {
missingBitmaps.add(bitmapId);
}
}
const { isOffscreenCanvasSupported } = this.evaluatorOptions;
if (missingBitmaps.size > 0) {
const annotationWithBitmaps = [];
for (const [key, annotation] of annotationStorage) {
if (!key.startsWith(AnnotationEditorPrefix)) {
continue;
}
if (annotation.bitmap && missingBitmaps.has(annotation.bitmapId)) {
annotationWithBitmaps.push(annotation);
}
}
// The array annotationWithBitmaps cannot be empty: the check above
// makes sure to have at least one annotation containing the bitmap.
imagePromises = AnnotationFactory.generateImages(
annotationWithBitmaps,
this.xref,
isOffscreenCanvasSupported
);
} else {
imagePromises = AnnotationFactory.generateImages(
newAnnotations,
this.xref,
isOffscreenCanvasSupported
);
}
deletedAnnotations = new RefSet();
this.#replaceIdByRef(newAnnotations, deletedAnnotations, null);
newAnnotationsPromise = AnnotationFactory.printNewAnnotations(
partialEvaluator,
task,
newAnnotations
newAnnotations,
imagePromises
);
}
}