Reorganization and cleanup

master
Sven Slootweg 7 years ago
parent 80d0fc828d
commit 4cdd2eaff6

@ -3,9 +3,7 @@
const canvassed = require("canvassed");
const objectPick = require("object.pick");
const tagParser = require("./tag-parser");
const layout = require("./layout");
const fromTree = require("./text-components/from-tree");
const setTextStyles = require("./render/set-text-styles");
const measureText = require("./render/measure-text");
@ -28,74 +26,22 @@ module.exports = function createTextShape(options) {
fontWeight: "normal",
lineHeight: 1.16,
onRender: function onRender(context) {
if (this.tags === true) {
let currentLineOffset = 0;
let currentComponentOffset = 0;
this._layout.forEach((line) => {
line.items.forEach((item) => {
setTextStyles(context, item.style);
context.fillText(item.text, currentComponentOffset, currentLineOffset - line.lineMinAscender);
currentComponentOffset += item.measurements.width;
});
currentLineOffset += line.lineHeight * this.lineHeight;
currentComponentOffset = 0;
});
} else {
let currentLineOffset = 0;
setTextStyles(context, getTextProperties(this));
console.log(this._lines, this.renderWidth, this.renderHeight);
this._lines.forEach((line) => {
context.fillText(line.text, 0, currentLineOffset - line.lineMinAscender);
currentLineOffset += line.measurements.height * this.lineHeight;
});
}
this._layout.items.forEach((item) => {
setTextStyles(context, item.style);
context.fillText(item.text, item.x, item.y);
});
},
onRecalculateSize: function onRecalculateSize() {
if (this.tags === true) {
this._layout = layout(this.text, {
classes: options.classes,
defaultStyle: getTextProperties(this)
});
let combinedLineHeight = this._layout.reduce((total, line, i) => {
if (i !== this._layout.length - 1) {
return total + (line.lineHeight * this.lineHeight);
} else {
/* The last line doesn't get a lineHeight multiplier... */
return total + line.lineHeight;
}
}, 0);
return {
height: Math.ceil(combinedLineHeight),
width: Math.ceil(Math.max.apply(null, this._layout.map(line => line.lineWidth)))
}
} else {
this._lines = this.text.split("\n").map((line) => {
return {
text: line,
measurements: measureText(line, getTextProperties(this))
}
});
console.log("line", this._lines)
function sum(values) {
return values.reduce((total, value) => {
return total + value;
}, 0);
}
let multipliedLineHeights = this._lines.slice(0, -1).map(line => line.measurements.height * this.lineHeight);
let combinedLineHeight = sum(multipliedLineHeights) + this._lines[this._lines.length - 1].measurements.height;
return {
height: Math.ceil(combinedLineHeight),
width: Math.ceil(Math.max.apply(null, this._lines.map(line => line.measurements.width)))
}
this._layout = layout(this.text, {
classes: options.classes,
defaultStyle: getTextProperties(this),
lineHeight: this.lineHeight,
tags: this.tags
});
return {
width: this._layout.width,
height: this._layout.height
}
}
}, options));

@ -1,49 +0,0 @@
'use strict';
const componentsToLines = require("./parser/to-lines");
const findAlignment = require("./parser/find-alignment");
const generateStyle = require("./parser/generate-style");
const fromTree = require("./parser/from-tree");
const tagParser = require("./parser/tag-parser");
const measureText = require("./render/measure-text");
module.exports = function layoutFormattedText(text, options) {
if (options.tags === true) {
let tree = tagParser.parse(text);
let lines = componentsToLines(fromTree(tree)).map((lineItems) => {
let measuredItems = lineItems.map((item) => {
let generatedStyle = generateStyle(item, {
classes: options.classes,
defaultStyle: options.defaultStyle
});
return Object.assign({
measurements: measureText(item.text, generatedStyle),
style: generatedStyle
}, item);
});
let combinedWidth = measuredItems.reduce((total, item) => {
return total + item.measurements.width;
}, 0);
let lineHeight = Math.max.apply(null, measuredItems.map(item => item.measurements.height));
let lineMinAscender = Math.min.apply(null, measuredItems.map(item => item.measurements.ascender));
let lineMaxDescender = Math.max.apply(null, measuredItems.map(item => item.measurements.descender));
return {
alignment: (lineItems.length > 0) ? findAlignment(lineItems[0]) : null,
items: measuredItems,
height: lineHeight,
width: combinedWidth,
minAscender: lineMinAscender,
maxDescender: lineMaxDescender
}
});
} else {
}
};

@ -0,0 +1,12 @@
'use strict';
module.exports = function adjustLineHeights(lines, lineHeight) {
return lines.map((line, i) => {
if (i !== lines.length - 1) {
return line.height * lineHeight * 1.13;
} else {
/* The last line doesn't get a lineHeight multiplier... */
return line.height * 1.13;
}
});
};

@ -0,0 +1,102 @@
'use strict';
const parser = require("../parser");
const findAlignment = require("../parser/find-alignment");
const generateStyle = require("../parser/generate-style");
const measureText = require("../render/measure-text");
const adjustLineHeights = require("./adjust-line-heights");
const sum = require("../util/sum");
const min = require("../util/min");
const max = require("../util/max");
module.exports = function layoutFormattedText(text, options) {
if (options.tags === true) {
let lines = parser(text).map((lineItems) => {
let measuredItems = lineItems.map((item) => {
let generatedStyle = generateStyle(item, {
classes: options.classes,
defaultStyle: options.defaultStyle
});
return Object.assign({
measurements: measureText(item.text, generatedStyle),
style: generatedStyle
}, item);
});
return {
alignment: (lineItems.length > 0) ? findAlignment(lineItems[0]) : null,
items: measuredItems,
height: max(measuredItems.map(item => item.measurements.height)),
width: sum(measuredItems.map(item => item.measurements.width)),
minAscender: min(measuredItems.map(item => item.measurements.ascender)),
maxDescender: max(measuredItems.map(item => item.measurements.descender))
}
});
let adjustedLineHeights = adjustLineHeights(lines, options.lineHeight);
let currentLineOffset = 0;
let currentComponentOffset = 0;
let positionedItems = lines.reduce((items, line, i) => {
let newItems = items.concat(line.items.map((item) => {
let positionedItem = Object.assign({
x: currentComponentOffset,
y: currentLineOffset - line.minAscender
}, item);
currentComponentOffset += item.measurements.width;
return positionedItem;
}));
currentLineOffset += adjustedLineHeights[i];
currentComponentOffset = 0;
return newItems;
}, []);
return {
width: Math.ceil(max(lines.map(line => line.width))),
height: Math.ceil(sum(adjustedLineHeights)),
items: positionedItems
}
} else {
let lines = text.split("\n").map((line) => {
return {
text: line,
measurements: measureText(line, options.defaultStyle)
};
});
let adjustedLineHeights = adjustLineHeights(lines.map((line) => {
return {
text: line.text,
height: line.measurements.height
}
}), options.lineHeight);
let currentLineOffset = 0;
let positionedItems = lines.map((line, i) => {
let newItem = {
text: line.text,
measurements: line.measurements,
style: options.defaultStyle,
x: 0,
y: currentLineOffset - line.measurements.ascender
}
currentLineOffset += adjustedLineHeights[i];
return newItem;
});
return {
width: Math.ceil(max(lines.map(line => line.measurements.width))),
height: Math.ceil(sum(adjustedLineHeights)),
items: positionedItems
}
}
};

@ -0,0 +1,9 @@
'use strict';
const componentsToLines = require("./to-lines");
const fromTree = require("./from-tree");
const tagParser = require("./tag-parser");
module.exports = function parseTextToLines(text) {
return componentsToLines(fromTree(tagParser.parse(text)));
};

@ -1,6 +1,6 @@
'use strict';
const findAlignment = require("../tags/find-alignment");
const findAlignment = require("./find-alignment");
module.exports = function componentsToLines(items) {
let currentLineItems = [];

@ -15,14 +15,6 @@ module.exports = function measureText(text, options) {
let fontMeasurements = measureFont(options.fontFamily);
return Object.assign(context.measureText(text), {
/* FIXME: The following is a dirty hack until the Canvas v5 API is
* widely supported in major browsers. The 1.13 multiplier comes
* from the fabric.js source code - don't ask me why it's 1.13.
* See also:
* https://kangax.github.io/jstests/canvas-v5/
* https://lists.w3.org/Archives/Public/public-whatwg-archive/2012Mar/0269.htm
*/
//height: options.fontSize * 1.13,
height: options.fontSize * (fontMeasurements.descender - fontMeasurements.topBounding),
ascender: options.fontSize * fontMeasurements.ascender,
descender: options.fontSize * fontMeasurements.descender,

@ -14,7 +14,7 @@ module.exports = function setTextStyles(context, options) {
options.fontVariant,
options.fontWeight,
`${options.fontSize}px`, // FIXME: Other units?
options.fontFamily
`'${options.fontFamily}'` // FIXME: Escaping of font family names containing a '
];
context.font = fontSegments.filter(segment => (segment != null)).join(" ");

@ -0,0 +1,5 @@
'use strict';
module.exports = function max(values) {
return Math.max(...values);
}

@ -0,0 +1,5 @@
'use strict';
module.exports = function min(values) {
return Math.min(...values);
}

@ -0,0 +1,7 @@
'use strict';
module.exports = function sum(values) {
return values.reduce((total, value) => {
return total + value;
}, 0);
};
Loading…
Cancel
Save