X-Git-Url: https://git.kianting.info/?a=blobdiff_plain;f=src%2Flibclo%2FbreakLines.js;fp=src%2Flibclo%2FbreakLines.js;h=e5d086563030a8d88c1c8a252f8db5416191a670;hb=f12842e5a4ef531e38024e16f91b21c99ce1de92;hp=27513f3c0f8e901060c66fc4f7643745c6a125fb;hpb=a4f79a3761539f45ac7d86fe919bdc32cf290db0;p=clo diff --git a/src/libclo/breakLines.js b/src/libclo/breakLines.js index 27513f3..e5d0865 100644 --- a/src/libclo/breakLines.js +++ b/src/libclo/breakLines.js @@ -1,95 +1,149 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.totalCost = void 0; +exports.BreakLineAlgorithm = void 0; /** - * Algorithms in LATEX language -TotalCost(i) = min_{j}~TotalCost(j) + LineCost(j, i)~~~~j=0, 1, ..., i-1 - -LineCost(j, i)= \begin{cases} -\infty ~~~ if~~LineWidth - \sum_{k=j+1}^{i-1} OrigWidth(item[k]) - newLineWidth(item[i]) < 0 \\ -\infty~~if~~NOT~~breakable(item[i]) \\ -(LineWidth - \sum_{k=j+1}^{i-1} OrigWidth(item[k]) - newLineWidth(item[i]))^3 ~~elsewhere -\end{cases} */ -/**check if a boeitem is BreakPoint Type */ -function isBreakPoint(item) { - return item.newLined !== undefined; -} -/**check if a boeitem is BreakPoint Type */ -function isHGlue(item) { - return item.stretchFactor !== undefined; -} -/** measuring original advance width */ -function origWidth(item) { - if (isBreakPoint(item)) { - console.log(item); - return origWidth(item.original); + * Algorithms in LATEX-like language + */ +class BreakLineAlgorithm { + constructor() { + this.prevNodes = []; + this.totalCostAuxStorage = []; + this.lineCostStorage = [[]]; } - else if (Array.isArray(item)) { - return item.map((x) => origWidth(x)) - .reduce((acc, current) => acc + current, 0.0); + /**check if a boeitem is BreakPoint Type */ + isBreakPoint(item) { + return item.newLined !== undefined; } - else if (isHGlue(item)) { - return 0.0; + /**check if a boeitem is BreakPoint Type */ + isHGlue(item) { + return item.stretchFactor !== undefined; } - else { - return item.width; + /** measuring original advance width */ + origWidth(item) { + if (this.isBreakPoint(item)) { + return this.origWidth(item.original); + } + else if (Array.isArray(item)) { + return item.map((x) => this.origWidth(x)) + .reduce((acc, current) => acc + current, 0.0); + } + else if (this.isHGlue(item)) { + return 0.0; + } + else { + return item.width; + } } -} -/** measuring new-line triggered advance width */ -function newLineWidth(item) { - if (isBreakPoint(item)) { - return origWidth(item.newLined); + segmentedNodes(items, lineWidth) { + this.totalCost(items, lineWidth); + let nodeList = this.generateBreakLineNodeList(); + console.log("~~~", nodeList); + let res = []; + let low = -1; + let up = nodeList[0]; + for (var i = 0; i < nodeList.length; i++) { + res.push(items.slice(low + 1, up + 1)); + low = nodeList[i]; + up = nodeList[i + 1]; + } + return res; } - else { - // impossible to make a new line - return Infinity; + /**genrate the list of point of breaking line. it returns a correct list ascending*/ + generateBreakLineNodeList() { + let res = []; + var pointer = this.prevNodes.length - 1; + while (this.prevNodes[pointer] !== undefined) { + res.push(pointer); + pointer = this.prevNodes[pointer]; + } + return res.reverse(); } -} -let lineCostStorage = new Object(); -/** - * check the total cost item[0..j]. - * @param items - * @param i - * @param lineWidth - */ -function totalCost(items, j, lineWidth) { - if (j in lineCostStorage) { - return lineCostStorage[j]; + /** measuring new-line triggered advance width */ + newLineWidth(item) { + if (this.isBreakPoint(item)) { + return this.origWidth(item.newLined); + } + else { + // impossible to make a new line + return Infinity; + } } - var returnCost = Infinity; - for (var i = -1; i <= j; i++) { - // lineCost - let lCost = lineCost(items, i, j, lineWidth); - if (returnCost > lCost) { - returnCost = lCost; + /** + * check all the total cost of paragraphes of the segnemt + */ + totalCost(items, lineWidth) { + let itemsLength = items.length; + this.lineCostStorage = Array(itemsLength); + this.prevNodes = Array(itemsLength).fill(null); + for (var i = 0; i < itemsLength; i++) { + this.lineCostStorage[i] = Array(itemsLength).fill(undefined); } + this.totalCostAuxStorage = Array(itemsLength).fill(undefined); + console.log("===", itemsLength); + let a = this.totalCostAux(items, itemsLength - 1, lineWidth); + console.log(this.lineCostStorage); + return a; } - lineCostStorage[j] = returnCost; - return returnCost; -} -exports.totalCost = totalCost; -/** - * check the line cost of a line containing items[i+1..j] - * @param items items of box - * @param i beginning (excluded) - * @param j end of the line - * @param lineWidth line width - */ -function lineCost(items, i, j, lineWidth) { - if (!isBreakPoint(items[j])) { - return Infinity; + /** + * check the total cost item[0..j]. + * @param items + * @param i + * @param lineWidth + */ + totalCostAux(items, j, lineWidth) { + if (this.totalCostAuxStorage[j] !== undefined) { + return this.totalCostAuxStorage[j]; + } + let rawLineCost = this.lineCost(items, 0, j, lineWidth); + if (rawLineCost != Infinity) { + this.totalCostAuxStorage[j] = rawLineCost; + return rawLineCost; + } + else { + var returnCost = Infinity; + for (var k = 0; k < j; k++) { + let tmp = this.totalCostAux(items, k, lineWidth) + this.lineCost(items, k + 1, j, lineWidth); + if (returnCost > tmp) { + this.prevNodes[j] = k; + returnCost = tmp; + } + } + this.totalCostAuxStorage[j] = returnCost; + return returnCost; + } + return returnCost; } - else { - var tmpItemWidth = 0; - for (var k = i + 1; k < j; k++) { - tmpItemWidth += origWidth(items[k]); + /** + * check the line cost of a line containing items[i..j] + * @param items items of box + * @param i beginning (excluded) + * @param j end of the line + * @param lineWidth line width + */ + lineCost(items, i, j, lineWidth) { + if (this.lineCostStorage[i] !== undefined && this.lineCostStorage[i][j] !== undefined) { + return this.lineCostStorage[i][j]; } - tmpItemWidth += newLineWidth(items[j]); - if (tmpItemWidth > lineWidth) { + if (!this.isBreakPoint(items[j])) { + this.lineCostStorage[i][j] = Infinity; return Infinity; } else { - return (lineWidth - tmpItemWidth) ** 3.0; + var tmpItemWidth = 0; + for (var k = i; k < j; k++) { + tmpItemWidth += this.origWidth(items[k]); + } + tmpItemWidth += this.newLineWidth(items[j]); + if (tmpItemWidth > lineWidth) { + this.lineCostStorage[i][j] = Infinity; + return Infinity; + } + else { + let returnValue = (lineWidth - tmpItemWidth) ** 3.0; + this.lineCostStorage[i][j] = returnValue; + return returnValue; + } } } } +exports.BreakLineAlgorithm = BreakLineAlgorithm;