]> git.kianting.info Git - clo/blob - src/libclo/breakLines.js
update readme
[clo] / src / libclo / breakLines.js
1 "use strict";
2 Object.defineProperty(exports, "__esModule", { value: true });
3 exports.BreakLineAlgorithm = void 0;
4 /**
5 * Algorithms in LATEX-like language
6 */
7 class BreakLineAlgorithm {
8 constructor() {
9 this.prevNodes = [];
10 this.totalCostAuxStorage = [];
11 this.lineCostStorage = [[]];
12 }
13 /**check if a boeitem is BreakPoint Type */
14 isBreakPoint(item) {
15 return item.newLined !== undefined;
16 }
17 /**check if a boeitem is HGlue Type */
18 isHGlue(item) {
19 return item.stretchFactor !== undefined;
20 }
21 /** measuring original advance width */
22 origWidth(item) {
23 if (this.isBreakPoint(item)) {
24 return this.origWidth(item.original);
25 }
26 else if (Array.isArray(item)) {
27 return item.map((x) => this.origWidth(x))
28 .reduce((acc, current) => acc + current, 0.0);
29 }
30 else if (this.isHGlue(item)) {
31 return 0.0;
32 }
33 else {
34 return item.width;
35 }
36 }
37 /**segement node of one paragraph into lines.
38 * @args items: nodes of a line
39 * @args linewidth: the line width
40 * @returns segmented nodes into lines
41 */
42 segmentedNodes(items, lineWidth) {
43 let lineWidthFixed = lineWidth;
44 this.totalCost(items, lineWidthFixed);
45 let nodeList = this.generateBreakLineNodeList();
46 let res = [];
47 let low = -1;
48 let up = nodeList[0];
49 for (var i = 0; i < nodeList.length; i++) {
50 res.push(items.slice(low + 1, up + 1));
51 low = nodeList[i];
52 up = nodeList[i + 1];
53 }
54 return res;
55 }
56 /**genrate the list of point of breaking line. it returns a correct list ascending*/
57 generateBreakLineNodeList() {
58 let res = [];
59 var pointer = this.prevNodes.length - 1;
60 while (this.prevNodes[pointer] !== undefined) {
61 res.push(pointer);
62 pointer = this.prevNodes[pointer];
63 }
64 return res.reverse();
65 }
66 /** measuring new-line triggered advance width */
67 newLineWidth(item) {
68 if (this.isBreakPoint(item)) {
69 return this.origWidth(item.newLined);
70 }
71 else {
72 // impossible to make a new line
73 return Infinity;
74 }
75 }
76 /**
77 * check all the total cost of paragraphes of the segnemt
78 */
79 totalCost(items, lineWidth) {
80 let lineWidthFixed = lineWidth * 0.75;
81 let itemsLength = items.length;
82 this.lineCostStorage = Array(itemsLength);
83 this.prevNodes = Array(itemsLength).fill(null);
84 for (var i = 0; i < itemsLength; i++) {
85 this.lineCostStorage[i] = Array(itemsLength).fill(null);
86 }
87 this.totalCostAuxStorage = Array(itemsLength).fill(null);
88 let a = Infinity;
89 for (var k = itemsLength - 2; this.lineCost(items, k + 1, itemsLength - 1, lineWidthFixed) < Infinity; k--) {
90 let tmp = this.totalCostAux(items, k, lineWidthFixed);
91 if (a > tmp) {
92 this.prevNodes[itemsLength - 1] = k;
93 a = tmp;
94 }
95 }
96 return a;
97 }
98 /**
99 * check the total cost item[0..j].
100 * @param items
101 * @param i
102 * @param lineWidth
103 */
104 totalCostAux(items, j, lineWidth) {
105 if (this.totalCostAuxStorage[j] !== null) {
106 return this.totalCostAuxStorage[j];
107 }
108 let rawLineCost = this.lineCost(items, 0, j, lineWidth);
109 if (rawLineCost != Infinity) {
110 this.totalCostAuxStorage[j] = rawLineCost ** 3.0;
111 return rawLineCost ** 3.0;
112 }
113 else {
114 var returnCost = Infinity;
115 for (var k = 0; k < j; k++) {
116 let tmp = this.totalCostAux(items, k, lineWidth) + this.lineCost(items, k + 1, j, lineWidth) ** 3.0;
117 if (returnCost > tmp) {
118 this.prevNodes[j] = k;
119 returnCost = tmp;
120 }
121 }
122 this.totalCostAuxStorage[j] = returnCost;
123 return returnCost;
124 }
125 }
126 /**
127 * check the line cost of a line containing items[i..j]
128 * @param items items of box
129 * @param i beginning (excluded)
130 * @param j end of the line
131 * @param lineWidth line width
132 */
133 lineCost(items, i, j, lineWidth) {
134 if (this.lineCostStorage[i][j] !== null) {
135 console.log("AA");
136 return this.lineCostStorage[i][j];
137 }
138 if (!this.isBreakPoint(items[j])) {
139 this.lineCostStorage[i][j] = Infinity;
140 return Infinity;
141 }
142 else {
143 var tmpItemWidth = 0;
144 for (var k = i; k < j; k++) {
145 tmpItemWidth += this.origWidth(items[k]);
146 }
147 tmpItemWidth += this.newLineWidth(items[j]);
148 if (tmpItemWidth > lineWidth) {
149 this.lineCostStorage[i][j] = Infinity;
150 return Infinity;
151 }
152 else {
153 let returnValue = (lineWidth - tmpItemWidth);
154 this.lineCostStorage[i][j] = returnValue;
155 return returnValue;
156 }
157 }
158 }
159 }
160 exports.BreakLineAlgorithm = BreakLineAlgorithm;