XFA - Implement aspect property on image element

- it aims to fix issue #13634;
  - move some img-related functions in test/drivers.js in order to have images in xfa reftests.
This commit is contained in:
Calixte Denizet 2021-06-27 17:17:44 +02:00
parent ff3a5382ee
commit 71d17b0cc4
5 changed files with 91 additions and 44 deletions

View File

@ -2829,11 +2829,38 @@ class Image extends StringObject {
if (this.transferEncoding === "base64") {
const buffer = stringToBytes(atob(this[$content]));
const blob = new Blob([buffer], { type: this.contentType });
let style;
switch (this.aspect) {
case "fit":
case "actual":
// TODO: check what to do with actual.
// Normally we should return {auto, auto} for it but
// it implies some wrong rendering (see xfa_bug1716816.pdf).
break;
case "height":
style = {
width: "auto",
height: "100%",
};
break;
case "none":
style = {
width: "100%",
height: "100%",
};
break;
case "width":
style = {
width: "100%",
height: "auto",
};
break;
}
return HTMLResult.success({
name: "img",
attributes: {
class: ["xfaImage"],
style: {},
style,
src: URL.createObjectURL(blob),
},
});

View File

@ -66,6 +66,54 @@ function writeSVG(svgElement, ctx, resolve, reject) {
};
}
function inlineImages(images) {
const imagePromises = [];
for (let i = 0, ii = images.length; i < ii; i++) {
imagePromises.push(
new Promise(function (resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.onload = function () {
const reader = new FileReader();
reader.onloadend = function () {
resolve(reader.result);
};
reader.readAsDataURL(xhr.response);
};
xhr.onerror = function (e) {
reject(new Error("Error fetching inline image " + e));
};
xhr.open("GET", images[i].src);
xhr.send();
})
);
}
return Promise.all(imagePromises);
}
async function resolveImages(node, silentErrors = false) {
const images = node.getElementsByTagName("img");
const data = await inlineImages(images);
const loadedPromises = [];
for (let i = 0, ii = data.length; i < ii; i++) {
images[i].src = data[i];
loadedPromises.push(
new Promise(function (resolveImage, rejectImage) {
images[i].onload = resolveImage;
images[i].onerror = function (e) {
if (silentErrors) {
resolveImage();
} else {
rejectImage(new Error("Error loading image " + e));
}
};
})
);
}
await Promise.all(loadedPromises);
}
/**
* @class
*/
@ -164,30 +212,6 @@ var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() {
return loadStyles(styles);
}
function inlineAnnotationImages(images) {
var imagePromises = [];
for (var i = 0, ii = images.length; i < ii; i++) {
var imagePromise = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.onload = function () {
var reader = new FileReader();
reader.onloadend = function () {
resolve(reader.result);
};
reader.readAsDataURL(xhr.response);
};
xhr.onerror = function (e) {
reject(new Error("Error fetching inline annotation image " + e));
};
xhr.open("GET", images[i].src);
xhr.send();
});
imagePromises.push(imagePromise);
}
return imagePromises;
}
// eslint-disable-next-line no-shadow
function rasterizeAnnotationLayer(
ctx,
@ -233,25 +257,7 @@ var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() {
pdfjsLib.AnnotationLayer.render(parameters);
// Inline SVG images from text annotations.
var images = div.getElementsByTagName("img");
var imagePromises = inlineAnnotationImages(images);
await Promise.all(imagePromises).then(function (data) {
var loadedPromises = [];
for (var i = 0, ii = data.length; i < ii; i++) {
images[i].src = data[i];
loadedPromises.push(
new Promise(function (resolveImage, rejectImage) {
images[i].onload = resolveImage;
images[i].onerror = function (e) {
rejectImage(new Error("Error loading image " + e));
};
})
);
}
return loadedPromises;
});
await resolveImages(div);
foreignObject.appendChild(div);
svg.appendChild(foreignObject);
@ -312,6 +318,9 @@ var rasterizeXfaLayer = (function rasterizeXfaLayerClosure() {
viewport: viewport.clone({ dontFlip: true }),
});
// Some unsupported type of images (e.g. tiff)
// lead to errors.
await resolveImages(div, /* silentErrors = */ true);
svg.appendChild(foreignObject);
writeSVG(svg, ctx, resolve, reject);

View File

@ -0,0 +1 @@
https://web.archive.org/web/20210510183636/https://guichet.public.lu/dam-assets/catalogue-formulaires/tva/tva-option-aic-pers-morales/tva-option-aic-pers-morale-DE.pdf

View File

@ -1050,6 +1050,14 @@
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_issue13634",
"file": "pdfs/xfa_issue13634.pdf",
"md5": "459a04045470811cbab6671772929d3d",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_issue13556",
"file": "pdfs/xfa_issue13556.pdf",
"md5": "197e93a010763c3b6f9845595ee66c70",

View File

@ -188,6 +188,8 @@
}
.xfaImage {
object-position: left top;
object-fit: contain;
width: 100%;
height: 100%;
}