Skip to content

Commit

Permalink
XFA - Display rectangle, line and arc
Browse files Browse the repository at this point in the history
  • Loading branch information
calixteman committed Jun 4, 2021
1 parent 417646e commit 3c40fb4
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 3 deletions.
136 changes: 134 additions & 2 deletions src/core/xfa/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import { stringToBytes, Util, warn } from "../../shared/util.js";
import { searchNode } from "./som.js";

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

// In case of lr-tb (and rl-tb) layouts, we try:
// - to put the container at the end of a line
Expand Down Expand Up @@ -226,6 +227,50 @@ class Arc extends XFAObject {
this.edge = null;
this.fill = null;
}

[$toHTML]() {
const edge = this.edge ? this.edge : new Edge({});
const edgeStyle = edge[$toStyle]();
const style = Object.create(null);
if (this.fill) {
Object.assign(style, this.fill[$toStyle]());
} else {
style.fill = "transparent";
}
style.strokeWidth = measureToString(Math.round(edge.thickness));
style.stroke = edgeStyle.color;
const startAngle = (this.startAngle * Math.PI) / 180;
const sweepAngle = (this.sweepAngle * Math.PI) / 180;
const arcSweep = this.sweepAngle - this.startAngle <= 180 ? 0 : 1;

const [x1, y1, x2, y2] = [
0.5 * (1 + Math.cos(startAngle)),
0.5 * (1 + Math.sin(startAngle)),
0.5 * (1 + Math.cos(sweepAngle)),
0.5 * (1 + Math.sin(sweepAngle)),
];

const arc = {
name: "path",
attributes: {
xmlns: SVG_NS,
d: `M ${x1} ${y1} A 0.5 0.5 0 ${arcSweep} 0 ${x2} ${y2} L 0.5 0.5 L ${x1} ${y1}`,
style,
},
};

return HTMLResult.success({
name: "svg",
children: [arc],
attributes: {
xmlns: SVG_NS,
style: {
width: "100%",
height: "100%",
},
},
});
}
}

class Area extends XFAObject {
Expand Down Expand Up @@ -1169,7 +1214,7 @@ class Corner extends XFAObject {
// Maybe it's possible to implement them using svg and border-image...
// TODO: implement all the missing properties.
const style = toStyle(this, "visibility");
style.radius = measureToString(this.radius);
style.radius = measureToString(this.join === "square" ? 0 : this.radius);
return style;
}
}
Expand Down Expand Up @@ -1484,7 +1529,7 @@ class Draw extends XFAObject {
}

html.children.push(value);
if (value.attributes.class.includes("xfaRich")) {
if (value.attributes.class && value.attributes.class.includes("xfaRich")) {
if (this.h === "") {
style.height = "auto";
}
Expand Down Expand Up @@ -2374,6 +2419,9 @@ class Fill extends XFAObject {
if (parent instanceof Border) {
propName = "background";
}
if (parent instanceof Rectangle) {
propName = "fill";
}
const style = Object.create(null);
for (const name of Object.getOwnPropertyNames(this)) {
if (name === "extras" || name === "color") {
Expand Down Expand Up @@ -2848,6 +2896,46 @@ class Line extends XFAObject {
this.usehref = attributes.usehref || "";
this.edge = null;
}

[$toHTML]() {
const edge = this.edge ? this.edge : new Edge({});
const edgeStyle = edge[$toStyle]();
const style = Object.create(null);
style.strokeWidth = measureToString(Math.round(edge.thickness));
style.stroke = edgeStyle.color;
let x1, y1, x2, y2;
if (this.slope === "\\") {
[x1, y1, x2, y2] = [0, 0, 1, 1];
} else {
[x1, y1, x2, y2] = [0, 1, 1, 0];
}

const line = {
name: "line",
attributes: {
xmlns: SVG_NS,
width: "100%",
height: "100%",
x1,
y1,
x2,
y2,
style,
},
};

return HTMLResult.success({
name: "svg",
children: [line],
attributes: {
xmlns: SVG_NS,
style: {
width: "100%",
height: "100%",
},
},
});
}
}

class Linear extends XFAObject {
Expand Down Expand Up @@ -3626,6 +3714,50 @@ class Rectangle extends XFAObject {
this.edge = new XFAObjectArray(4);
this.fill = null;
}

[$toHTML]() {
const edge = this.edge.children.length
? this.edge.children[0]
: new Edge({});
const edgeStyle = edge[$toStyle]();
const style = Object.create(null);
if (this.fill) {
Object.assign(style, this.fill[$toStyle]());
} else {
style.fill = "transparent";
}
style.strokeWidth = measureToString(Math.round(edge.thickness));
style.stroke = edgeStyle.color;

const corner = this.corner.children.length
? this.corner.children[0]
: new Corner({});
const cornerStyle = corner[$toStyle]();

const rect = {
name: "rect",
attributes: {
xmlns: SVG_NS,
width: "100%",
height: "100%",
rx: cornerStyle.radius,
ry: cornerStyle.radius,
style,
},
};

return HTMLResult.success({
name: "svg",
children: [rect],
attributes: {
xmlns: SVG_NS,
style: {
width: "100%",
height: "100%",
},
},
});
}
}

class RefElement extends StringObject {
Expand Down
9 changes: 8 additions & 1 deletion src/display/xfa_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,14 @@ class XfaLayer {
continue;
}

const childHtml = document.createElement(name);
let childHtml;
if (child?.attributes?.xmlns) {
childHtml = document.createElementNS(child.attributes.xmlns, name);
delete child.attributes.xmlns;
} else {
childHtml = document.createElement(name);
}

html.appendChild(childHtml);
if (child.attributes) {
this.setAttributes(childHtml, child, storage, intent);
Expand Down

0 comments on commit 3c40fb4

Please sign in to comment.