mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-06-12 13:11:07 +02:00
Merge pull request #21413 from calixteman/improve_comb
Improve rendering of comb text fields
This commit is contained in:
commit
a13f2aa793
@ -2559,7 +2559,6 @@ class WidgetAnnotation extends Annotation {
|
||||
fontSize,
|
||||
totalWidth,
|
||||
totalHeight,
|
||||
defaultHPadding,
|
||||
defaultVPadding,
|
||||
descent,
|
||||
lineHeight,
|
||||
@ -2924,7 +2923,6 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
||||
fontSize,
|
||||
width,
|
||||
height,
|
||||
hPadding,
|
||||
vPadding,
|
||||
descent,
|
||||
lineHeight,
|
||||
@ -2936,24 +2934,34 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
||||
// Empty or it has a trailing whitespace.
|
||||
const colors = this.getBorderAndBackgroundAppearances(annotationStorage);
|
||||
|
||||
const buf = [];
|
||||
const positions = font.getCharPositions(text);
|
||||
for (const [start, end] of positions) {
|
||||
buf.push(`(${escapeString(text.substring(start, end))}) Tj`);
|
||||
}
|
||||
const cells = font.getCharPositions(text).map(([start, end]) => {
|
||||
const glyph = text.substring(start, end);
|
||||
return { glyph, width: this._getTextWidth(glyph, font) * fontSize };
|
||||
});
|
||||
if (isRTL) {
|
||||
buf.reverse();
|
||||
cells.reverse();
|
||||
}
|
||||
|
||||
const textWidth = combWidth * positions.length;
|
||||
let hShift = hPadding;
|
||||
const textWidth = combWidth * cells.length;
|
||||
let hShift = 0;
|
||||
if (alignment === 1) {
|
||||
hShift += Math.floor((width - textWidth) / (2 * combWidth)) * combWidth;
|
||||
} else if (alignment === 2) {
|
||||
hShift += width - textWidth;
|
||||
}
|
||||
|
||||
const renderedComb = buf.join(` ${numberToString(combWidth)} 0 Td `);
|
||||
const buf = [];
|
||||
let previousWidth = 0;
|
||||
for (let i = 0, ii = cells.length; i < ii; i++) {
|
||||
const { glyph, width: glyphWidth } = cells[i];
|
||||
const shift =
|
||||
i === 0
|
||||
? (combWidth - glyphWidth) / 2
|
||||
: combWidth + (previousWidth - glyphWidth) / 2;
|
||||
buf.push(`${numberToString(shift)} 0 Td (${escapeString(glyph)}) Tj`);
|
||||
previousWidth = glyphWidth;
|
||||
}
|
||||
const renderedComb = buf.join(" ");
|
||||
return (
|
||||
`/Tx BMC q ${colors}BT ` +
|
||||
defaultAppearance +
|
||||
|
||||
@ -1450,7 +1450,7 @@ class WidgetAnnotationElement extends AnnotationElement {
|
||||
|
||||
style.color = Util.makeHexColor(...fontColor);
|
||||
|
||||
if (this.data.textAlignment !== null) {
|
||||
if (this.data.textAlignment !== null && !this.data.comb) {
|
||||
style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
|
||||
}
|
||||
}
|
||||
@ -1879,7 +1879,30 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
||||
const combWidth = fieldWidth / maxLen;
|
||||
|
||||
element.classList.add("comb");
|
||||
element.style.letterSpacing = `calc(${combWidth}px * var(--total-scale-factor) - 1ch)`;
|
||||
element.style.setProperty(
|
||||
"--comb-width",
|
||||
`calc(${combWidth}px * var(--total-scale-factor))`
|
||||
);
|
||||
|
||||
const alignment = this.data.textAlignment;
|
||||
if (alignment === 1 || alignment === 2) {
|
||||
const setCombOffset = () => {
|
||||
const free = maxLen - element.value.length;
|
||||
element.style.setProperty(
|
||||
"--comb-offset",
|
||||
`${alignment === 1 ? free >> 1 : free}`
|
||||
);
|
||||
};
|
||||
setCombOffset();
|
||||
for (const evt of [
|
||||
"input",
|
||||
"blur",
|
||||
"resetform",
|
||||
"updatefromsandbox",
|
||||
]) {
|
||||
element.addEventListener(evt, setCombOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
element = document.createElement("div");
|
||||
|
||||
@ -2051,11 +2051,11 @@ describe("annotation", function () {
|
||||
annotationStorage
|
||||
);
|
||||
expect(appearance).toEqual(
|
||||
"/Tx BMC q BT /Helv 5 Tf 1 0 0 1 2 3.07 Tm" +
|
||||
" (a) Tj 8 0 Td (a) Tj 8 0 Td (\\() Tj" +
|
||||
" 8 0 Td (a) Tj 8 0 Td (a) Tj" +
|
||||
" 8 0 Td (\\)) Tj 8 0 Td (a) Tj" +
|
||||
" 8 0 Td (\\\\) Tj ET Q EMC"
|
||||
"/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 3.07 Tm" +
|
||||
" 2.61 0 Td (a) Tj 8 0 Td (a) Tj 8.56 0 Td (\\() Tj" +
|
||||
" 7.44 0 Td (a) Tj 8 0 Td (a) Tj" +
|
||||
" 8.56 0 Td (\\)) Tj 7.44 0 Td (a) Tj" +
|
||||
" 8.7 0 Td (\\\\) Tj ET Q EMC"
|
||||
);
|
||||
});
|
||||
|
||||
@ -2092,8 +2092,8 @@ describe("annotation", function () {
|
||||
annotationStorage
|
||||
);
|
||||
expect(appearance).toEqual(
|
||||
"/Tx BMC q BT /Goth 5 Tf 1 0 0 1 2 3.07 Tm" +
|
||||
" (\x30\x53) Tj 8 0 Td (\x30\x93) Tj 8 0 Td (\x30\x6b) Tj" +
|
||||
"/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 3.07 Tm" +
|
||||
" 1.5 0 Td (\x30\x53) Tj 8 0 Td (\x30\x93) Tj 8 0 Td (\x30\x6b) Tj" +
|
||||
" 8 0 Td (\x30\x61) Tj 8 0 Td (\x30\x6f) Tj" +
|
||||
" 8 0 Td (\x4e\x16) Tj 8 0 Td (\x75\x4c) Tj" +
|
||||
" 8 0 Td (\x30\x6e) Tj ET Q EMC"
|
||||
|
||||
@ -292,19 +292,25 @@
|
||||
}
|
||||
|
||||
.textWidgetAnnotation input.comb {
|
||||
--comb-width: 0px;
|
||||
--comb-letter-spacing: calc(var(--comb-width) - 1ch);
|
||||
|
||||
font-family: monospace;
|
||||
padding-left: 2px;
|
||||
padding-right: 0;
|
||||
letter-spacing: var(--comb-letter-spacing);
|
||||
overflow-x: hidden;
|
||||
padding: 0;
|
||||
text-indent: calc(
|
||||
var(--comb-offset, 0) * var(--comb-width) + var(--comb-letter-spacing) / 2
|
||||
);
|
||||
}
|
||||
|
||||
.textWidgetAnnotation input.comb:focus {
|
||||
/*
|
||||
* Letter spacing is placed on the right side of each character. Hence, the
|
||||
* letter spacing of the last character may be placed outside the visible
|
||||
* area, causing horizontal scrolling. We avoid this by extending the width
|
||||
* when the element has focus and revert this when it loses focus.
|
||||
*/
|
||||
width: 103%;
|
||||
background-image: repeating-linear-gradient(
|
||||
to right,
|
||||
transparent 0 calc(var(--comb-width) - 1px),
|
||||
var(--input-focus-border-color) calc(var(--comb-width) - 1px)
|
||||
var(--comb-width)
|
||||
);
|
||||
}
|
||||
|
||||
.buttonWidgetAnnotation:is(.checkBox, .radioButton) input {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user