Skip to content

Commit 4af35ca

Browse files
committed
XFA - Convert some template properties into CSS ones
- implement few positioning properties: position, width, height, anchor; - implement font element; - implement fill element (used by font) and its children (linear, radial, ...); - font property is inherited from ancestor container (see https://www.pdfa.org/wp-content/uploads/2020/07/XFA-3_3.pdf#page=43) so let CSS handles that stuff; - in order to reduce the number of properties to set, only set non default properties and put the default in CSS; - set a background to some containers to be able to see them (will be removed in a future commit).
1 parent f043a94 commit 4af35ca

10 files changed

+546
-90
lines changed

src/core/xfa/html_utils.js

+91-40
Original file line numberDiff line numberDiff line change
@@ -13,57 +13,108 @@
1313
* limitations under the License.
1414
*/
1515

16-
const converters = {
17-
pt: x => x,
18-
cm: x => Math.round((x / 2.54) * 72),
19-
mm: x => Math.round((x / (10 * 2.54)) * 72),
20-
in: x => Math.round(x * 72),
21-
};
16+
import { $toStyle, XFAObject } from "./xfa_object.js";
17+
import { warn } from "../../shared/util.js";
2218

2319
function measureToString(m) {
24-
const conv = converters[m.unit];
25-
if (conv) {
26-
return `${conv(m.value)}px`;
27-
}
28-
return `${m.value}${m.unit}`;
20+
return Number.isInteger(m) ? `${m}px` : `${m.toFixed(2)}px`;
2921
}
3022

31-
function setWidthHeight(node, style) {
32-
if (node.w) {
33-
style.width = measureToString(node.w);
34-
} else {
35-
if (node.maxW && node.maxW.value > 0) {
36-
style.maxWidth = measureToString(node.maxW);
23+
const converters = {
24+
anchorType(node, style) {
25+
if (!("transform" in style)) {
26+
style.transform = "";
3727
}
38-
if (node.minW && node.minW.value > 0) {
39-
style.minWidth = measureToString(node.minW);
28+
switch (node.anchorType) {
29+
case "bottomCenter":
30+
style.transform += "translate(-50%, -100%)";
31+
break;
32+
case "bottomLeft":
33+
style.transform += "translate(0,-100%)";
34+
break;
35+
case "bottomRight":
36+
style.transform += "translate(-100%,-100%)";
37+
break;
38+
case "middleCenter":
39+
style.transform += "translate(-50%,-50%)";
40+
break;
41+
case "middleLeft":
42+
style.transform += "translate(0,-50%)";
43+
break;
44+
case "middleRight":
45+
style.transform += "translate(-100%,-50%)";
46+
break;
47+
case "topCenter":
48+
style.transform += "translate(-50%,0)";
49+
break;
50+
case "topRight":
51+
style.transform += "translate(-100%,0)";
52+
break;
53+
}
54+
},
55+
dimensions(node, style) {
56+
if (node.w) {
57+
style.width = measureToString(node.w);
58+
} else {
59+
if (node.maxW && node.maxW.value > 0) {
60+
style.maxWidth = measureToString(node.maxW);
61+
}
62+
if (node.minW && node.minW.value > 0) {
63+
style.minWidth = measureToString(node.minW);
64+
}
4065
}
41-
}
4266

43-
if (node.h) {
44-
style.height = measureToString(node.h);
45-
} else {
46-
if (node.maxH && node.maxH.value > 0) {
47-
style.maxHeight = measureToString(node.maxH);
67+
if (node.h) {
68+
style.height = measureToString(node.h);
69+
} else {
70+
if (node.maxH && node.maxH.value > 0) {
71+
style.maxHeight = measureToString(node.maxH);
72+
}
73+
if (node.minH && node.minH.value > 0) {
74+
style.minHeight = measureToString(node.minH);
75+
}
4876
}
49-
if (node.minH && node.minH.value > 0) {
50-
style.minHeight = measureToString(node.minH);
77+
},
78+
position(node, style) {
79+
if (node.x !== "" || node.y !== "") {
80+
style.position = "absolute";
81+
style.left = measureToString(node.x);
82+
style.top = measureToString(node.y);
5183
}
52-
}
53-
}
84+
},
85+
rotate(node, style) {
86+
if (node.rotate) {
87+
if (!("transform" in style)) {
88+
style.transform = "";
89+
}
90+
style.transform += `rotate(-${node.rotate}deg)`;
91+
style.transformOrigin = "top left";
92+
}
93+
},
94+
};
5495

55-
function setPosition(node, style) {
56-
style.transform = "";
57-
if (node.rotate) {
58-
style.transform = `rotate(-${node.rotate}deg) `;
59-
style.transformOrigin = "top left";
60-
}
96+
function toStyle(node, ...names) {
97+
const style = Object.create(null);
98+
for (const name of names) {
99+
const value = node[name];
100+
if (value === null) {
101+
continue;
102+
}
103+
if (value instanceof XFAObject) {
104+
const newStyle = value[$toStyle]();
105+
if (newStyle) {
106+
Object.assign(style, newStyle);
107+
} else {
108+
warn(`(DEBUG) - XFA - style for ${name} not implemented yet`);
109+
}
110+
continue;
111+
}
61112

62-
if (node.x !== "" || node.y !== "") {
63-
style.position = "absolute";
64-
style.left = node.x ? measureToString(node.x) : "0pt";
65-
style.top = node.y ? measureToString(node.y) : "0pt";
113+
if (converters.hasOwnProperty(name)) {
114+
converters[name](node, style);
115+
}
66116
}
117+
return style;
67118
}
68119

69-
export { measureToString, setPosition, setWidthHeight };
120+
export { measureToString, toStyle };

0 commit comments

Comments
 (0)