Merge pull request #14936 from calixteman/input_font_size

Set the text fields font size based on their height
This commit is contained in:
calixteman 2022-05-28 18:32:45 +02:00 committed by GitHub
commit 9bdf27e8e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 104 additions and 47 deletions

View File

@ -24,6 +24,7 @@ import {
escapeString,
getModificationDate,
isAscii,
LINE_FACTOR,
OPS,
RenderingIntentFlag,
shadow,
@ -55,11 +56,6 @@ import { StringStream } from "./stream.js";
import { writeDict } from "./writer.js";
import { XFAFactory } from "./xfa/factory.js";
// Represent the percentage of the height of a single-line field over
// the font size.
// Acrobat seems to use this value.
const LINE_FACTOR = 1.35;
class AnnotationFactory {
/**
* Create an `Annotation` object of the correct type for the given reference
@ -1921,6 +1917,7 @@ class TextWidgetAnnotation extends WidgetAnnotation {
!this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) &&
!this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) &&
this.data.maxLen !== null;
this.data.doNotScroll = this.hasFieldFlag(AnnotationFieldFlag.DONOTSCROLL);
}
_getCombAppearance(defaultAppearance, font, text, width, hPadding, vPadding) {
@ -2788,6 +2785,9 @@ class LinkAnnotation extends Annotation {
this.data.quadPoints = quadPoints;
}
// The color entry for a link annotation is the color of the border.
this.data.borderColor = this.data.borderColor || this.data.color;
Catalog.parseDestDictionary({
destDict: params.dict,
resultObj: this.data,

View File

@ -22,6 +22,7 @@ import {
AnnotationBorderStyleType,
AnnotationType,
assert,
LINE_FACTOR,
shadow,
unreachable,
Util,
@ -37,6 +38,7 @@ import { ColorConverters } from "../shared/scripting_utils.js";
import { XfaLayer } from "./xfa_layer.js";
const DEFAULT_TAB_INDEX = 1000;
const DEFAULT_FONT_SIZE = 9;
const GetElementsByNameSet = new WeakSet();
function getRectDims(rect) {
@ -271,12 +273,12 @@ class AnnotationElement {
break;
}
const borderColor = data.borderColor || data.color || null;
const borderColor = data.borderColor || null;
if (borderColor) {
container.style.borderColor = Util.makeHexColor(
data.color[0] | 0,
data.color[1] | 0,
data.color[2] | 0
borderColor[0] | 0,
borderColor[1] | 0,
borderColor[2] | 0
);
} else {
// Transparent (invisible) border, so do not draw it at all.
@ -897,6 +899,53 @@ class WidgetAnnotationElement extends AnnotationElement {
? "transparent"
: Util.makeHexColor(color[0], color[1], color[2]);
}
/**
* Apply text styles to the text in the element.
*
* @private
* @param {HTMLDivElement} element
* @memberof TextWidgetAnnotationElement
*/
_setTextStyle(element) {
const TEXT_ALIGNMENT = ["left", "center", "right"];
const { fontColor } = this.data.defaultAppearanceData;
const fontSize =
this.data.defaultAppearanceData.fontSize || DEFAULT_FONT_SIZE;
const style = element.style;
// TODO: If the font-size is zero, calculate it based on the height and
// width of the element.
// Not setting `style.fontSize` will use the default font-size for now.
// We don't use the font, as specified in the PDF document, for the <input>
// element. Hence using the original `fontSize` could look bad, which is why
// it's instead based on the field height.
// If the height is "big" then it could lead to a too big font size
// so in this case use the one we've in the pdf (hence the min).
if (this.data.multiLine) {
const height = Math.abs(this.data.rect[3] - this.data.rect[1]);
const numberOfLines = Math.round(height / (LINE_FACTOR * fontSize)) || 1;
const lineHeight = height / numberOfLines;
style.fontSize = `${Math.min(
fontSize,
Math.round(lineHeight / LINE_FACTOR)
)}px`;
} else {
const height = Math.abs(this.data.rect[3] - this.data.rect[1]);
style.fontSize = `${Math.min(
fontSize,
Math.round(height / LINE_FACTOR)
)}px`;
}
style.color = Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]);
if (this.data.textAlignment !== null) {
style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
}
}
}
class TextWidgetAnnotationElement extends WidgetAnnotationElement {
@ -944,10 +993,16 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
if (this.data.multiLine) {
element = document.createElement("textarea");
element.textContent = textContent;
if (this.data.doNotScroll) {
element.style.overflowY = "hidden";
}
} else {
element = document.createElement("input");
element.type = "text";
element.setAttribute("value", textContent);
if (this.data.doNotScroll) {
element.style.overflowX = "hidden";
}
}
GetElementsByNameSet.add(element);
element.disabled = this.data.readOnly;
@ -1177,32 +1232,6 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
this.container.appendChild(element);
return this.container;
}
/**
* Apply text styles to the text in the element.
*
* @private
* @param {HTMLDivElement} element
* @memberof TextWidgetAnnotationElement
*/
_setTextStyle(element) {
const TEXT_ALIGNMENT = ["left", "center", "right"];
const { fontSize, fontColor } = this.data.defaultAppearanceData;
const style = element.style;
// TODO: If the font-size is zero, calculate it based on the height and
// width of the element.
// Not setting `style.fontSize` will use the default font-size for now.
if (fontSize) {
style.fontSize = `${fontSize}px`;
}
style.color = Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]);
if (this.data.textAlignment !== null) {
style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
}
}
}
class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
@ -1413,10 +1442,8 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
value: this.data.fieldValue,
});
let { fontSize } = this.data.defaultAppearanceData;
if (!fontSize) {
fontSize = 9;
}
const fontSize =
this.data.defaultAppearanceData.fontSize || DEFAULT_FONT_SIZE;
const fontSizeStyle = `calc(${fontSize}px * var(--zoom-factor))`;
const selectElement = document.createElement("select");
@ -1426,8 +1453,6 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
selectElement.setAttribute("id", id);
selectElement.tabIndex = DEFAULT_TAB_INDEX;
selectElement.style.fontSize = `${fontSize}px`;
if (!this.data.combo) {
// List boxes have a size and (optionally) multiple selection.
selectElement.size = this.data.options.length;
@ -1606,6 +1631,12 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
});
}
if (this.data.combo) {
this._setTextStyle(selectElement);
} else {
// Just use the default font size...
// it's a bit hard to guess what is a good size.
}
this._setBackgroundColor(selectElement);
this._setDefaultPropertiesFromJS(selectElement);

View File

@ -18,6 +18,10 @@ import "./compatibility.js";
const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
// Represent the percentage of the height of a single-line field over
// the font size. Acrobat seems to use this value.
const LINE_FACTOR = 1.35;
/**
* Refer to the `WorkerTransport.getRenderingIntent`-method in the API, to see
* how these flags are being used:
@ -1162,6 +1166,7 @@ export {
isArrayBuffer,
isArrayEqual,
isAscii,
LINE_FACTOR,
MissingPDFException,
objectFromMap,
objectSize,

View File

@ -751,7 +751,9 @@ class Driver {
transform,
};
if (renderForms) {
renderContext.annotationMode = AnnotationMode.ENABLE_FORMS;
renderContext.annotationMode = task.annotationStorage
? AnnotationMode.ENABLE_STORAGE
: AnnotationMode.ENABLE_FORMS;
} else if (renderPrint) {
if (task.annotationStorage) {
renderContext.annotationMode = AnnotationMode.ENABLE_STORAGE;

View File

@ -0,0 +1,2 @@
https://github.com/mozilla/pdf.js/files/7594316/formulairecerfa90nov00-1.pdf

View File

@ -6507,5 +6507,26 @@
"rounds": 1,
"link": true,
"type": "other"
},
{ "id": "issue14301",
"file": "pdfs/issue14301.pdf",
"md5": "9973936dcf8dd41daa62c04a4eb621f0",
"rounds": 1,
"link": true,
"firstPage": 2,
"lastPage": 2,
"type": "eq",
"forms": true,
"annotationStorage": {
"1832R": {
"value": "3"
},
"1827R": {
"value": "2"
},
"1808R": {
"value": "1"
}
}
}
]

View File

@ -59,10 +59,9 @@
background-image: var(--annotation-unfocused-field-background);
border: 1px solid transparent;
box-sizing: border-box;
font-size: 9px;
font: 9px sans-serif;
height: 100%;
margin: 0;
padding: 0 3px;
vertical-align: top;
width: 100%;
}
@ -76,8 +75,6 @@
}
.annotationLayer .textWidgetAnnotation textarea {
font: message-box;
font-size: 9px;
resize: none;
}
@ -167,7 +164,6 @@
.annotationLayer .buttonWidgetAnnotation.checkBox input,
.annotationLayer .buttonWidgetAnnotation.radioButton input {
appearance: none;
padding: 0;
}
.annotationLayer .popupWrapper {