1
0
Fork 0

Added new layout setting to bypass bin packing

This commit is contained in:
Joost De Cock 2019-01-13 15:00:01 +01:00
parent 33785b5311
commit eee6c2814a
5 changed files with 82 additions and 171 deletions

View file

@ -11,8 +11,8 @@ import Attributes from "./attributes";
export default function Pattern(config = { options: {} }) { export default function Pattern(config = { options: {} }) {
this.config = config; // Pattern configuration this.config = config; // Pattern configuration
this.width = false; // Will be set after render this.width = 0; // Will be set after render
this.height = false; // Will be set after render this.height = 0; // Will be set after render
this.is = ""; // Will be set when drafting/sampling this.is = ""; // Will be set when drafting/sampling
this.store = new Store(); // Store for sharing data across parts this.store = new Store(); // Store for sharing data across parts
@ -31,6 +31,7 @@ export default function Pattern(config = { options: {} }) {
locale: "en", locale: "en",
units: "metric", units: "metric",
margin: 2, margin: 2,
layout: true,
options: {} options: {}
}; };
@ -383,16 +384,19 @@ Pattern.prototype.pack = function() {
for (let key in this.parts) { for (let key in this.parts) {
let part = this.parts[key]; let part = this.parts[key];
// Avoid multiple render calls to cause stacking of transforms // Avoid multiple render calls to cause stacking of transforms
part.attributes.set("transform", ""); part.attributes.remove("transform");
if (part.render && this.needs(key)) { if (part.render && this.needs(key)) {
part.stack(); part.stack();
bins.push({ let width = part.bottomRight.x - part.topLeft.x;
id: key, let height = part.bottomRight.y - part.topLeft.y;
width: part.bottomRight.x - part.topLeft.x, if (this.settings.layout) bins.push({ id: key, width, height });
height: part.bottomRight.y - part.topLeft.y else {
}); if (this.width < width) this.width = width;
if (this.height < height) this.height = height;
} }
} }
}
if (this.settings.layout) {
let size = pack(bins, { inPlace: true }); let size = pack(bins, { inPlace: true });
for (let bin of bins) { for (let bin of bins) {
let part = this.parts[bin.id]; let part = this.parts[bin.id];
@ -401,6 +405,7 @@ Pattern.prototype.pack = function() {
} }
this.width = size.width; this.width = size.width;
this.height = size.height; this.height = size.height;
}
return this; return this;
}; };

View file

@ -4,12 +4,11 @@ import { version } from "../package.json";
function Svg(pattern) { function Svg(pattern) {
this.openGroups = []; this.openGroups = [];
this.layout = {};
this.freeId = 0; this.freeId = 0;
this.body = ""; this.body = "";
this.style = ""; this.style = "";
this.script = ""; this.script = "";
this.header = "";
this.footer = "";
this.defs = ""; this.defs = "";
this.pattern = pattern; // Needed to expose pattern to hooks this.pattern = pattern; // Needed to expose pattern to hooks
this.prefix = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'; this.prefix = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';
@ -52,39 +51,59 @@ Svg.prototype.debug = function() {};
Svg.prototype.render = function(pattern) { Svg.prototype.render = function(pattern) {
this.idPrefix = pattern.settings.idPrefix; this.idPrefix = pattern.settings.idPrefix;
this.runHooks("preRender"); this.runHooks("preRender");
//this.preRender();
if (!pattern.settings.embed) { if (!pattern.settings.embed) {
this.attributes.add("width", pattern.width + "mm"); this.attributes.add("width", pattern.width + "mm");
this.attributes.add("height", pattern.height + "mm"); this.attributes.add("height", pattern.height + "mm");
} }
this.attributes.add("viewBox", `0 0 ${pattern.width} ${pattern.height}`); this.attributes.add("viewBox", `0 0 ${pattern.width} ${pattern.height}`);
this.svg = this.prefix; this.head = this.renderHead();
this.svg += this.renderComments(this.header); this.tail = this.renderTail();
this.svg += this.renderSvgTag(pattern); this.svg = "";
this.svg += this.renderStyle(); this.layout = {}; // Reset layout
this.svg += this.renderScript();
this.svg += this.renderDefs();
this.svg += this.openGroup(this.idPrefix + "container");
for (let partId in pattern.parts) { for (let partId in pattern.parts) {
let part = pattern.parts[partId]; let part = pattern.parts[partId];
if (part.render && pattern.needs(partId)) { if (part.render && pattern.needs(partId)) {
let partSvg = this.renderPart(part);
this.layout[partId] = {
svg: partSvg,
transform: part.attributes.getAsArray("transform")
};
this.svg += this.openGroup( this.svg += this.openGroup(
`${this.idPrefix}part-${partId}`, `${this.idPrefix}part-${partId}`,
part.attributes part.attributes
); );
this.svg += this.renderPart(part); this.svg += partSvg;
this.svg += this.closeGroup(); this.svg += this.closeGroup();
} }
} }
this.svg += this.closeGroup(); this.svg =
this.svg += this.nl() + "</svg>"; this.prefix + this.renderSvgTag() + this.head + this.svg + this.tail;
this.svg += this.renderComments(this.footer);
this.runHooks("postRender"); this.runHooks("postRender");
return this.svg; return this.svg;
}; };
/** Renders SVG head section */
Svg.prototype.renderHead = function() {
let svg = this.renderStyle();
svg += this.renderScript();
svg += this.renderDefs();
svg += this.openGroup(this.idPrefix + "container");
return svg;
};
/** Renders SVG closing section */
Svg.prototype.renderTail = function() {
let svg = "";
svg += this.closeGroup();
svg += this.nl() + "</svg>";
return svg;
};
/** Returns SVG code for the opening SVG tag */ /** Returns SVG code for the opening SVG tag */
Svg.prototype.renderSvgTag = function(pattern) { Svg.prototype.renderSvgTag = function() {
let svg = "<svg"; let svg = "<svg";
this.indent(); this.indent();
svg += this.nl() + this.attributes.render(); svg += this.nl() + this.attributes.render();
@ -126,13 +145,6 @@ Svg.prototype.renderDefs = function() {
return svg; return svg;
}; };
/** Returns SVG code for a comment block */
Svg.prototype.renderComments = function(comments) {
return (
this.nl() + this.nl() + "<!--" + this.nl() + comments + this.nl() + "-->"
);
};
/** Returns SVG code for a Part object */ /** Returns SVG code for a Part object */
Svg.prototype.renderPart = function(part) { Svg.prototype.renderPart = function(part) {
let svg = ""; let svg = "";

View file

@ -1,11 +1,7 @@
var version = require("../../package.json").version; var version = require("../../package.json").version;
var render = { var render = {
boilerplate: `<?xml version="1.0" encoding="UTF-8" standalone="no"?> boilerplate: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -25,16 +21,8 @@ var render = {
<g id="fs-container"> <g id="fs-container">
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
boilerplateNl: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
boilerplateNl: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="nl" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="nl" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="0mm" height="0mm" viewBox="0 0 0 0"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -54,16 +42,8 @@ var render = {
<g id="fs-container"> <g id="fs-container">
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
embed: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
embed: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" viewBox="0 0 0 0" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" viewBox="0 0 0 0"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -83,16 +63,8 @@ var render = {
<g id="fs-container"> <g id="fs-container">
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
part: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
part: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -117,16 +89,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
path: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
path: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -152,16 +116,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
text: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
text: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -188,16 +144,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
circle: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
circle: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="104mm" height="104mm" viewBox="0 0 104 104" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="104mm" height="104mm" viewBox="0 0 104 104"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -227,16 +175,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
multiText: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
multiText: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -263,16 +203,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
multiTextDflt: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
multiTextDflt: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -299,16 +231,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
textOnPath: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
textOnPath: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -336,16 +260,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
textOnPathCenter: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
textOnPathCenter: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -373,16 +289,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
textOnPathRight: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
textOnPathRight: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="44mm" height="56.45mm" viewBox="0 0 44 56.45"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -410,16 +318,8 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`,
snippet: `<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
<!--
-->`,
snippet: `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
--><svg
xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" xmlns:freesewing="http://freesewing.org/namespaces/freesewing" freesewing="${version}" width="4mm" height="4mm" viewBox="0 0 4 4"
> >
<style type="text/css"> <![CDATA[ <style type="text/css"> <![CDATA[
@ -445,11 +345,7 @@ var render = {
<!-- end of group #fs-part-test --> <!-- end of group #fs-part-test -->
</g> </g>
<!-- end of group #fs-container --> <!-- end of group #fs-container -->
</svg> </svg>`
<!--
-->`
}; };
module.exports = render; module.exports = render;

View file

@ -9,8 +9,8 @@ it("Pattern constructor should initialize object", () => {
percentage: { pct: 30, min: 0, max: 100 } percentage: { pct: 30, min: 0, max: 100 }
} }
}); });
expect(pattern.width).to.equal(false); expect(pattern.width).to.equal(0);
expect(pattern.height).to.equal(false); expect(pattern.height).to.equal(0);
expect(pattern.settings.complete).to.equal(true); expect(pattern.settings.complete).to.equal(true);
expect(pattern.parts).to.eql({}); expect(pattern.parts).to.eql({});
expect(pattern.settings.units).to.equal("metric"); expect(pattern.settings.units).to.equal("metric");

View file

@ -15,9 +15,7 @@ it("Svg constructor should initialize object", () => {
expect(svg.body).to.equal(""); expect(svg.body).to.equal("");
expect(svg.style).to.equal(""); expect(svg.style).to.equal("");
expect(svg.script).to.equal(""); expect(svg.script).to.equal("");
expect(svg.header).to.equal("");
expect(svg.defs).to.equal(""); expect(svg.defs).to.equal("");
expect(svg.footer).to.equal("");
expect(svg.pattern).to.eql(pattern); expect(svg.pattern).to.eql(pattern);
expect(svg.prefix).to.equal( expect(svg.prefix).to.equal(
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>' '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'