Skip to content

Commit 6cfa247

Browse files
committed
XFA - Display rectangle, line and arc
1 parent f6628b0 commit 6cfa247

File tree

2 files changed

+142
-3
lines changed

2 files changed

+142
-3
lines changed

src/core/xfa/template.js

+134-2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import { stringToBytes, Util, warn } from "../../shared/util.js";
7979
import { searchNode } from "./som.js";
8080

8181
const TEMPLATE_NS_ID = NamespaceIds.template.id;
82+
const SVG_NS = "http://www.w3.org/2000/svg";
8283

8384
// In case of lr-tb (and rl-tb) layouts, we try:
8485
// - to put the container at the end of a line
@@ -226,6 +227,50 @@ class Arc extends XFAObject {
226227
this.edge = null;
227228
this.fill = null;
228229
}
230+
231+
[$toHTML]() {
232+
const edge = this.edge ? this.edge : new Edge({});
233+
const edgeStyle = edge[$toStyle]();
234+
const style = Object.create(null);
235+
if (this.fill) {
236+
Object.assign(style, this.fill[$toStyle]());
237+
} else {
238+
style.fill = "transparent";
239+
}
240+
style.strokeWidth = measureToString(Math.round(edge.thickness));
241+
style.stroke = edgeStyle.color;
242+
const startAngle = (this.startAngle * Math.PI) / 180;
243+
const sweepAngle = (this.sweepAngle * Math.PI) / 180;
244+
const arcSweep = this.sweepAngle - this.startAngle <= 180 ? 0 : 1;
245+
246+
const [x1, y1, x2, y2] = [
247+
0.5 * (1 + Math.cos(startAngle)),
248+
0.5 * (1 + Math.sin(startAngle)),
249+
0.5 * (1 + Math.cos(sweepAngle)),
250+
0.5 * (1 + Math.sin(sweepAngle)),
251+
];
252+
253+
const arc = {
254+
name: "path",
255+
attributes: {
256+
xmlns: SVG_NS,
257+
d: `M ${x1} ${y1} A 0.5 0.5 0 ${arcSweep} 0 ${x2} ${y2} L 0.5 0.5 L ${x1} ${y1}`,
258+
style,
259+
},
260+
};
261+
262+
return HTMLResult.success({
263+
name: "svg",
264+
children: [arc],
265+
attributes: {
266+
xmlns: SVG_NS,
267+
style: {
268+
width: "100%",
269+
height: "100%",
270+
},
271+
},
272+
});
273+
}
229274
}
230275

231276
class Area extends XFAObject {
@@ -1169,7 +1214,7 @@ class Corner extends XFAObject {
11691214
// Maybe it's possible to implement them using svg and border-image...
11701215
// TODO: implement all the missing properties.
11711216
const style = toStyle(this, "visibility");
1172-
style.radius = measureToString(this.radius);
1217+
style.radius = measureToString(this.join === "square" ? 0 : this.radius);
11731218
return style;
11741219
}
11751220
}
@@ -1484,7 +1529,7 @@ class Draw extends XFAObject {
14841529
}
14851530

14861531
html.children.push(value);
1487-
if (value.attributes.class.includes("xfaRich")) {
1532+
if (value.attributes.class && value.attributes.class.includes("xfaRich")) {
14881533
if (this.h === "") {
14891534
style.height = "auto";
14901535
}
@@ -2374,6 +2419,9 @@ class Fill extends XFAObject {
23742419
if (parent instanceof Border) {
23752420
propName = "background";
23762421
}
2422+
if (parent instanceof Rectangle) {
2423+
propName = "fill";
2424+
}
23772425
const style = Object.create(null);
23782426
for (const name of Object.getOwnPropertyNames(this)) {
23792427
if (name === "extras" || name === "color") {
@@ -2848,6 +2896,46 @@ class Line extends XFAObject {
28482896
this.usehref = attributes.usehref || "";
28492897
this.edge = null;
28502898
}
2899+
2900+
[$toHTML]() {
2901+
const edge = this.edge ? this.edge : new Edge({});
2902+
const edgeStyle = edge[$toStyle]();
2903+
const style = Object.create(null);
2904+
style.strokeWidth = measureToString(Math.round(edge.thickness));
2905+
style.stroke = edgeStyle.color;
2906+
let x1, y1, x2, y2;
2907+
if (this.slope === "\\") {
2908+
[x1, y1, x2, y2] = [0, 0, 1, 1];
2909+
} else {
2910+
[x1, y1, x2, y2] = [0, 1, 1, 0];
2911+
}
2912+
2913+
const line = {
2914+
name: "line",
2915+
attributes: {
2916+
xmlns: SVG_NS,
2917+
width: "100%",
2918+
height: "100%",
2919+
x1,
2920+
y1,
2921+
x2,
2922+
y2,
2923+
style,
2924+
},
2925+
};
2926+
2927+
return HTMLResult.success({
2928+
name: "svg",
2929+
children: [line],
2930+
attributes: {
2931+
xmlns: SVG_NS,
2932+
style: {
2933+
width: "100%",
2934+
height: "100%",
2935+
},
2936+
},
2937+
});
2938+
}
28512939
}
28522940

28532941
class Linear extends XFAObject {
@@ -3626,6 +3714,50 @@ class Rectangle extends XFAObject {
36263714
this.edge = new XFAObjectArray(4);
36273715
this.fill = null;
36283716
}
3717+
3718+
[$toHTML]() {
3719+
const edge = this.edge.children.length
3720+
? this.edge.children[0]
3721+
: new Edge({});
3722+
const edgeStyle = edge[$toStyle]();
3723+
const style = Object.create(null);
3724+
if (this.fill) {
3725+
Object.assign(style, this.fill[$toStyle]());
3726+
} else {
3727+
style.fill = "transparent";
3728+
}
3729+
style.strokeWidth = measureToString(Math.round(edge.thickness));
3730+
style.stroke = edgeStyle.color;
3731+
3732+
const corner = this.corner.children.length
3733+
? this.corner.children[0]
3734+
: new Corner({});
3735+
const cornerStyle = corner[$toStyle]();
3736+
3737+
const rect = {
3738+
name: "rect",
3739+
attributes: {
3740+
xmlns: SVG_NS,
3741+
width: "100%",
3742+
height: "100%",
3743+
rx: cornerStyle.radius,
3744+
ry: cornerStyle.radius,
3745+
style,
3746+
},
3747+
};
3748+
3749+
return HTMLResult.success({
3750+
name: "svg",
3751+
children: [rect],
3752+
attributes: {
3753+
xmlns: SVG_NS,
3754+
style: {
3755+
width: "100%",
3756+
height: "100%",
3757+
},
3758+
},
3759+
});
3760+
}
36293761
}
36303762

36313763
class RefElement extends StringObject {

src/display/xfa_layer.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,14 @@ class XfaLayer {
163163
continue;
164164
}
165165

166-
const childHtml = document.createElement(name);
166+
let childHtml;
167+
if (child?.attributes?.xmlns) {
168+
childHtml = document.createElementNS(child.attributes.xmlns, name);
169+
delete child.attributes.xmlns;
170+
} else {
171+
childHtml = document.createElement(name);
172+
}
173+
167174
html.appendChild(childHtml);
168175
if (child.attributes) {
169176
this.setAttributes(childHtml, child, storage, intent);

0 commit comments

Comments
 (0)