Merge pull request #12361 from Snuffleupagus/_getSaveFieldResources

Ensure that all necessary /Font resources are included when saving a `WidgetAnnotation`-instance (issue 12294)
This commit is contained in:
Tim van der Meij 2020-09-15 00:09:31 +02:00 committed by GitHub
commit b0c7a74a0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 15 deletions

View File

@ -919,10 +919,18 @@ class WidgetAnnotation extends Annotation {
""; "";
const fieldType = getInheritableProperty({ dict, key: "FT" }); const fieldType = getInheritableProperty({ dict, key: "FT" });
data.fieldType = isName(fieldType) ? fieldType.name : null; data.fieldType = isName(fieldType) ? fieldType.name : null;
this.fieldResources =
getInheritableProperty({ dict, key: "DR" }) || const localResources = getInheritableProperty({ dict, key: "DR" });
params.acroForm.get("DR") || const acroFormResources = params.acroForm.get("DR");
Dict.empty; this._fieldResources = {
localResources,
acroFormResources,
mergedResources: Dict.merge({
xref: params.xref,
dictArray: [localResources, acroFormResources],
mergeSubDicts: true,
}),
};
data.fieldFlags = getInheritableProperty({ dict, key: "Ff" }); data.fieldFlags = getInheritableProperty({ dict, key: "Ff" });
if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) { if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) {
@ -1077,7 +1085,7 @@ class WidgetAnnotation extends Annotation {
.getOperatorList({ .getOperatorList({
stream, stream,
task, task,
resources: this.fieldResources, resources: this._fieldResources.mergedResources,
operatorList, operatorList,
}) })
.then(function () { .then(function () {
@ -1101,8 +1109,9 @@ class WidgetAnnotation extends Annotation {
if (appearance === null) { if (appearance === null) {
return null; return null;
} }
const { xref } = evaluator;
const dict = evaluator.xref.fetchIfRef(this.ref); const dict = xref.fetchIfRef(this.ref);
if (!isDict(dict)) { if (!isDict(dict)) {
return null; return null;
} }
@ -1120,11 +1129,11 @@ class WidgetAnnotation extends Annotation {
value, value,
}; };
const newRef = evaluator.xref.getNewRef(); const newRef = xref.getNewRef();
const AP = new Dict(evaluator.xref); const AP = new Dict(xref);
AP.set("N", newRef); AP.set("N", newRef);
const encrypt = evaluator.xref.encrypt; const encrypt = xref.encrypt;
let originalTransform = null; let originalTransform = null;
let newTransform = null; let newTransform = null;
if (encrypt) { if (encrypt) {
@ -1140,10 +1149,10 @@ class WidgetAnnotation extends Annotation {
dict.set("AP", AP); dict.set("AP", AP);
dict.set("M", `D:${getModificationDate()}`); dict.set("M", `D:${getModificationDate()}`);
const appearanceDict = new Dict(evaluator.xref); const appearanceDict = new Dict(xref);
appearanceDict.set("Length", appearance.length); appearanceDict.set("Length", appearance.length);
appearanceDict.set("Subtype", Name.get("Form")); appearanceDict.set("Subtype", Name.get("Form"));
appearanceDict.set("Resources", this.fieldResources); appearanceDict.set("Resources", this._getSaveFieldResources(xref));
appearanceDict.set("BBox", bbox); appearanceDict.set("BBox", bbox);
const bufferOriginal = [`${this.ref.num} ${this.ref.gen} obj\n`]; const bufferOriginal = [`${this.ref.num} ${this.ref.gen} obj\n`];
@ -1166,6 +1175,8 @@ class WidgetAnnotation extends Annotation {
} }
async _getAppearance(evaluator, task, annotationStorage) { async _getAppearance(evaluator, task, annotationStorage) {
this._fontName = null;
const isPassword = this.hasFieldFlag(AnnotationFieldFlag.PASSWORD); const isPassword = this.hasFieldFlag(AnnotationFieldFlag.PASSWORD);
if (!annotationStorage || isPassword) { if (!annotationStorage || isPassword) {
return null; return null;
@ -1182,9 +1193,8 @@ class WidgetAnnotation extends Annotation {
const fontInfo = await this._getFontData(evaluator, task); const fontInfo = await this._getFontData(evaluator, task);
const [font, fontName] = fontInfo; const [font, fontName] = fontInfo;
let fontSize = fontInfo[2]; const fontSize = this._computeFontSize(...fontInfo, totalHeight);
this._fontName = fontName;
fontSize = this._computeFontSize(font, fontName, fontSize, totalHeight);
let descent = font.descent; let descent = font.descent;
if (isNaN(descent)) { if (isNaN(descent)) {
@ -1260,7 +1270,7 @@ class WidgetAnnotation extends Annotation {
await evaluator.getOperatorList({ await evaluator.getOperatorList({
stream: new StringStream(this.data.defaultAppearance), stream: new StringStream(this.data.defaultAppearance),
task, task,
resources: this.fieldResources, resources: this._fieldResources.mergedResources,
operatorList, operatorList,
initialState, initialState,
}); });
@ -1314,6 +1324,49 @@ class WidgetAnnotation extends Annotation {
return `${shift} ${vPadding} Td (${escapeString(text)}) Tj`; return `${shift} ${vPadding} Td (${escapeString(text)}) Tj`;
} }
/**
* @private
*/
_getSaveFieldResources(xref) {
if (
typeof PDFJSDev === "undefined" ||
PDFJSDev.test("!PRODUCTION || TESTING")
) {
assert(
this._fontName !== undefined,
"Expected `_getAppearance()` to have been called."
);
}
const { localResources, acroFormResources } = this._fieldResources;
if (!this._fontName) {
return localResources || Dict.empty;
}
if (localResources instanceof Dict) {
const localFont = localResources.get("Font");
if (localFont instanceof Dict && localFont.has(this._fontName)) {
return localResources;
}
}
if (acroFormResources instanceof Dict) {
const acroFormFont = acroFormResources.get("Font");
if (acroFormFont instanceof Dict && acroFormFont.has(this._fontName)) {
const subFontDict = new Dict(xref);
subFontDict.set(this._fontName, acroFormFont.getRaw(this._fontName));
const subResourcesDict = new Dict(xref);
subResourcesDict.set("Font", subFontDict);
return Dict.merge({
xref,
dictArray: [subResourcesDict, localResources],
mergeSubDicts: true,
});
}
}
return localResources || Dict.empty;
}
} }
class TextWidgetAnnotation extends WidgetAnnotation { class TextWidgetAnnotation extends WidgetAnnotation {

View File

@ -0,0 +1 @@
https://web.archive.org/web/20200914130729/https://www.nta.go.jp/taxes/tetsuzuki/shinsei/annai/joyaku/annai/pdf2/250.pdf

View File

@ -2780,6 +2780,18 @@
"rounds": 1, "rounds": 1,
"type": "eq" "type": "eq"
}, },
{ "id": "issue12294-print",
"file": "pdfs/issue12294.pdf",
"md5": "a0ac5e03be38b5fb7a7a615e30024b28",
"rounds": 1,
"lastPage": 1,
"link": true,
"type": "eq",
"print": true,
"annotationStorage": {
"2795R": "氏 名 又 は 名 称 Full name"
}
},
{ "id": "issue7598", { "id": "issue7598",
"file": "pdfs/issue7598.pdf", "file": "pdfs/issue7598.pdf",
"md5": "c5bc5a779bfcb4b234f853231b56cf60", "md5": "c5bc5a779bfcb4b234f853231b56cf60",