XFA - Add support to print XFA forms
This commit is contained in:
parent
8c53bf8647
commit
a434011517
@ -13,6 +13,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { PageViewport } from "./display_utils.js";
|
||||||
|
|
||||||
class XfaLayer {
|
class XfaLayer {
|
||||||
static setupStorage(html, fieldId, element, storage) {
|
static setupStorage(html, fieldId, element, storage) {
|
||||||
const storedData = storage.getValue(fieldId, { value: null });
|
const storedData = storage.getValue(fieldId, { value: null });
|
||||||
@ -100,7 +102,12 @@ class XfaLayer {
|
|||||||
|
|
||||||
const rootDiv = parameters.div;
|
const rootDiv = parameters.div;
|
||||||
rootDiv.appendChild(rootHtml);
|
rootDiv.appendChild(rootHtml);
|
||||||
const coeffs = parameters.viewport.transform.join(",");
|
|
||||||
|
let { viewport } = parameters;
|
||||||
|
if (!(viewport instanceof PageViewport)) {
|
||||||
|
viewport = new PageViewport(viewport);
|
||||||
|
}
|
||||||
|
const coeffs = viewport.transform.join(",");
|
||||||
rootDiv.style.transform = `matrix(${coeffs})`;
|
rootDiv.style.transform = `matrix(${coeffs})`;
|
||||||
|
|
||||||
// Set defaults.
|
// Set defaults.
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { RenderingCancelledException, shadow } from "pdfjs-lib";
|
import { RenderingCancelledException, shadow } from "pdfjs-lib";
|
||||||
|
import { getXfaHtmlForPrinting } from "./ui_utils.js";
|
||||||
import { PDFPrintServiceFactory } from "./app.js";
|
import { PDFPrintServiceFactory } from "./app.js";
|
||||||
|
|
||||||
// Creates a placeholder with div and canvas with right size for the page.
|
// Creates a placeholder with div and canvas with right size for the page.
|
||||||
@ -33,6 +34,7 @@ function composePage(
|
|||||||
canvas.height = Math.floor(size.height * PRINT_UNITS);
|
canvas.height = Math.floor(size.height * PRINT_UNITS);
|
||||||
|
|
||||||
const canvasWrapper = document.createElement("div");
|
const canvasWrapper = document.createElement("div");
|
||||||
|
canvasWrapper.setAttribute("class", "printedPage");
|
||||||
canvasWrapper.appendChild(canvas);
|
canvasWrapper.appendChild(canvas);
|
||||||
printContainer.appendChild(canvasWrapper);
|
printContainer.appendChild(canvasWrapper);
|
||||||
|
|
||||||
@ -130,6 +132,11 @@ FirefoxPrintService.prototype = {
|
|||||||
const body = document.querySelector("body");
|
const body = document.querySelector("body");
|
||||||
body.setAttribute("data-pdfjsprinting", true);
|
body.setAttribute("data-pdfjsprinting", true);
|
||||||
|
|
||||||
|
if (pdfDocument.isPureXfa) {
|
||||||
|
getXfaHtmlForPrinting(printContainer, pdfDocument);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0, ii = pagesOverview.length; i < ii; ++i) {
|
for (let i = 0, ii = pagesOverview.length; i < ii; ++i) {
|
||||||
composePage(
|
composePage(
|
||||||
pdfDocument,
|
pdfDocument,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { PDFPrintServiceFactory, PDFViewerApplication } from "./app.js";
|
import { PDFPrintServiceFactory, PDFViewerApplication } from "./app.js";
|
||||||
|
import { getXfaHtmlForPrinting } from "./ui_utils.js";
|
||||||
import { viewerCompatibilityParams } from "./viewer_compatibility.js";
|
import { viewerCompatibilityParams } from "./viewer_compatibility.js";
|
||||||
|
|
||||||
let activeService = null;
|
let activeService = null;
|
||||||
@ -139,6 +140,11 @@ PDFPrintService.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderPages() {
|
renderPages() {
|
||||||
|
if (this.pdfDocument.isPureXfa) {
|
||||||
|
getXfaHtmlForPrinting(this.printContainer, this.pdfDocument);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
const pageCount = this.pagesOverview.length;
|
const pageCount = this.pagesOverview.length;
|
||||||
const renderNextPage = (resolve, reject) => {
|
const renderNextPage = (resolve, reject) => {
|
||||||
this.throwIfInactive();
|
this.throwIfInactive();
|
||||||
@ -157,8 +163,10 @@ PDFPrintService.prototype = {
|
|||||||
this._printResolution,
|
this._printResolution,
|
||||||
this._optionalContentConfigPromise
|
this._optionalContentConfigPromise
|
||||||
)
|
)
|
||||||
.then(this.useRenderedPage.bind(this))
|
.then(() => {
|
||||||
.then(function () {
|
this.useRenderedPage.bind(this);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
renderNextPage(resolve, reject);
|
renderNextPage(resolve, reject);
|
||||||
}, reject);
|
}, reject);
|
||||||
};
|
};
|
||||||
@ -181,6 +189,7 @@ PDFPrintService.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const wrapper = document.createElement("div");
|
const wrapper = document.createElement("div");
|
||||||
|
wrapper.setAttribute("class", "printedPage");
|
||||||
wrapper.appendChild(img);
|
wrapper.appendChild(img);
|
||||||
this.printContainer.appendChild(wrapper);
|
this.printContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { DefaultXfaLayerFactory } from "./xfa_layer_builder.js";
|
||||||
|
|
||||||
const CSS_UNITS = 96.0 / 72.0;
|
const CSS_UNITS = 96.0 / 72.0;
|
||||||
const DEFAULT_SCALE_VALUE = "auto";
|
const DEFAULT_SCALE_VALUE = "auto";
|
||||||
const DEFAULT_SCALE = 1.0;
|
const DEFAULT_SCALE = 1.0;
|
||||||
@ -994,6 +996,29 @@ function apiPageModeToSidebarView(mode) {
|
|||||||
return SidebarView.NONE; // Default value.
|
return SidebarView.NONE; // Default value.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getXfaHtmlForPrinting(printContainer, pdfDocument) {
|
||||||
|
const xfaHtml = pdfDocument.allXfaHtml;
|
||||||
|
const factory = new DefaultXfaLayerFactory();
|
||||||
|
const scale = Math.round(CSS_UNITS * 100) / 100;
|
||||||
|
for (const xfaPage of xfaHtml.children) {
|
||||||
|
const page = document.createElement("div");
|
||||||
|
page.setAttribute("class", "xfaPrintedPage");
|
||||||
|
printContainer.appendChild(page);
|
||||||
|
|
||||||
|
const { width, height } = xfaPage.attributes.style;
|
||||||
|
const viewBox = [0, 0, parseInt(width), parseInt(height)];
|
||||||
|
const viewport = { viewBox, scale, rotation: 0 };
|
||||||
|
|
||||||
|
const builder = factory.createXfaLayerBuilder(
|
||||||
|
page,
|
||||||
|
null,
|
||||||
|
pdfDocument.annotationStorage,
|
||||||
|
xfaPage
|
||||||
|
);
|
||||||
|
builder.render(viewport, "print");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
animationStarted,
|
animationStarted,
|
||||||
apiPageLayoutToSpreadMode,
|
apiPageLayoutToSpreadMode,
|
||||||
@ -1010,6 +1035,7 @@ export {
|
|||||||
getOutputScale,
|
getOutputScale,
|
||||||
getPageSizeInches,
|
getPageSizeInches,
|
||||||
getVisibleElements,
|
getVisibleElements,
|
||||||
|
getXfaHtmlForPrinting,
|
||||||
isPortraitOrientation,
|
isPortraitOrientation,
|
||||||
isValidRotation,
|
isValidRotation,
|
||||||
isValidScrollMode,
|
isValidScrollMode,
|
||||||
|
@ -1772,7 +1772,8 @@ html[dir="rtl"] #documentPropertiesOverlay .row > * {
|
|||||||
.toolbar,
|
.toolbar,
|
||||||
#loadingBox,
|
#loadingBox,
|
||||||
#errorWrapper,
|
#errorWrapper,
|
||||||
.textLayer {
|
.textLayer,
|
||||||
|
.canvasWrapper {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#viewerContainer {
|
#viewerContainer {
|
||||||
@ -1816,7 +1817,7 @@ html[dir="rtl"] #documentPropertiesOverlay .row > * {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
/* wrapper around (scaled) print canvas elements */
|
/* wrapper around (scaled) print canvas elements */
|
||||||
#printContainer > div {
|
#printContainer > .printedPage {
|
||||||
page-break-after: always;
|
page-break-after: always;
|
||||||
page-break-inside: avoid;
|
page-break-inside: avoid;
|
||||||
|
|
||||||
@ -1829,8 +1830,17 @@ html[dir="rtl"] #documentPropertiesOverlay .row > * {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
#printContainer canvas,
|
|
||||||
#printContainer img {
|
#printContainer > .xfaPrintedPage {
|
||||||
|
page-break-after: always;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printedPage canvas,
|
||||||
|
.printedPage img {
|
||||||
/* The intrinsic canvas / image size will make sure that we fit the page. */
|
/* The intrinsic canvas / image size will make sure that we fit the page. */
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
@ -262,3 +262,10 @@
|
|||||||
.xfaTable .xfaRlRow > div {
|
.xfaTable .xfaRlRow > div {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.xfaTextfield,
|
||||||
|
.xfaSelect {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -26,9 +26,10 @@ class XfaLayerBuilder {
|
|||||||
/**
|
/**
|
||||||
* @param {XfaLayerBuilderOptions} options
|
* @param {XfaLayerBuilderOptions} options
|
||||||
*/
|
*/
|
||||||
constructor({ pageDiv, pdfPage, annotationStorage }) {
|
constructor({ pageDiv, pdfPage, xfaHtml, annotationStorage }) {
|
||||||
this.pageDiv = pageDiv;
|
this.pageDiv = pageDiv;
|
||||||
this.pdfPage = pdfPage;
|
this.pdfPage = pdfPage;
|
||||||
|
this.xfaHtml = xfaHtml;
|
||||||
this.annotationStorage = annotationStorage;
|
this.annotationStorage = annotationStorage;
|
||||||
|
|
||||||
this.div = null;
|
this.div = null;
|
||||||
@ -42,34 +43,55 @@ class XfaLayerBuilder {
|
|||||||
* annotations is complete.
|
* annotations is complete.
|
||||||
*/
|
*/
|
||||||
render(viewport, intent = "display") {
|
render(viewport, intent = "display") {
|
||||||
return this.pdfPage
|
if (intent === "display") {
|
||||||
.getXfa()
|
return this.pdfPage
|
||||||
.then(xfa => {
|
.getXfa()
|
||||||
if (this._cancelled) {
|
.then(xfa => {
|
||||||
return;
|
if (this._cancelled) {
|
||||||
}
|
return;
|
||||||
const parameters = {
|
}
|
||||||
viewport: viewport.clone({ dontFlip: true }),
|
const parameters = {
|
||||||
div: this.div,
|
viewport: viewport.clone({ dontFlip: true }),
|
||||||
xfa,
|
div: this.div,
|
||||||
page: this.pdfPage,
|
xfa,
|
||||||
annotationStorage: this.annotationStorage,
|
page: this.pdfPage,
|
||||||
};
|
annotationStorage: this.annotationStorage,
|
||||||
|
};
|
||||||
|
|
||||||
if (this.div) {
|
if (this.div) {
|
||||||
XfaLayer.update(parameters);
|
XfaLayer.update(parameters);
|
||||||
} else {
|
} else {
|
||||||
// Create an xfa layer div and render the form
|
// Create an xfa layer div and render the form
|
||||||
this.div = document.createElement("div");
|
this.div = document.createElement("div");
|
||||||
this.pageDiv.appendChild(this.div);
|
this.pageDiv.appendChild(this.div);
|
||||||
parameters.div = this.div;
|
parameters.div = this.div;
|
||||||
|
|
||||||
XfaLayer.render(parameters);
|
XfaLayer.render(parameters);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// intent === "print".
|
||||||
|
viewport.dontFlip = true;
|
||||||
|
const parameters = {
|
||||||
|
viewport,
|
||||||
|
div: this.div,
|
||||||
|
xfa: this.xfaHtml,
|
||||||
|
page: null,
|
||||||
|
annotationStorage: this.annotationStorage,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an xfa layer div and render the form
|
||||||
|
const div = document.createElement("div");
|
||||||
|
this.pageDiv.appendChild(div);
|
||||||
|
parameters.div = div;
|
||||||
|
|
||||||
|
XfaLayer.render(parameters);
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
@ -92,12 +114,19 @@ class DefaultXfaLayerFactory {
|
|||||||
* @param {HTMLDivElement} pageDiv
|
* @param {HTMLDivElement} pageDiv
|
||||||
* @param {PDFPage} pdfPage
|
* @param {PDFPage} pdfPage
|
||||||
* @param {AnnotationStorage} [annotationStorage]
|
* @param {AnnotationStorage} [annotationStorage]
|
||||||
|
* @param {Object} [xfaHtml]
|
||||||
*/
|
*/
|
||||||
createXfaLayerBuilder(pageDiv, pdfPage, annotationStorage = null) {
|
createXfaLayerBuilder(
|
||||||
|
pageDiv,
|
||||||
|
pdfPage,
|
||||||
|
annotationStorage = null,
|
||||||
|
xfaHtml = null
|
||||||
|
) {
|
||||||
return new XfaLayerBuilder({
|
return new XfaLayerBuilder({
|
||||||
pageDiv,
|
pageDiv,
|
||||||
pdfPage,
|
pdfPage,
|
||||||
annotationStorage,
|
annotationStorage,
|
||||||
|
xfaHtml,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user