]> git.kianting.info Git - clo/blob - src/libclo/breakLines.js
f194aa5657eb8cb9edc734418cb0fbe1afc95d13
[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 segmentedNodes(items, lineWidth) {
38 let lineWidthFixed = lineWidth;
39 this.totalCost(items, lineWidthFixed);
40 let nodeList = this.generateBreakLineNodeList();
41 let res = [];
42 let low = -1;
43 let up = nodeList[0];
44 for (var i = 0; i < nodeList.length; i++) {
45 res.push(items.slice(low + 1, up + 1));
46 low = nodeList[i];
47 up = nodeList[i + 1];
48 }
49 return res;
50 }
51 /**genrate the list of point of breaking line. it returns a correct list ascending*/
52 generateBreakLineNodeList() {
53 let res = [];
54 var pointer = this.prevNodes.length - 1;
55 while (this.prevNodes[pointer] !== undefined) {
56 res.push(pointer);
57 pointer = this.prevNodes[pointer];
58 }
59 return res.reverse();
60 }
61 /** measuring new-line triggered advance width */
62 newLineWidth(item) {
63 if (this.isBreakPoint(item)) {
64 return this.origWidth(item.newLined);
65 }
66 else {
67 // impossible to make a new line
68 return Infinity;
69 }
70 }
71 /**
72 * check all the total cost of paragraphes of the segnemt
73 */
74 totalCost(items, lineWidth) {
75 let lineWidthFixed = lineWidth * 0.75;
76 let itemsLength = items.length;
77 this.lineCostStorage = Array(itemsLength);
78 this.prevNodes = Array(itemsLength).fill(null);
79 for (var i = 0; i < itemsLength; i++) {
80 this.lineCostStorage[i] = Array(itemsLength).fill(null);
81 }
82 this.totalCostAuxStorage = Array(itemsLength).fill(null);
83 let a = Infinity;
84 for (var k = itemsLength - 2; this.lineCost(items, k + 1, itemsLength - 1, lineWidthFixed) < Infinity; k--) {
85 let tmp = this.totalCostAux(items, k, lineWidthFixed);
86 if (a > tmp) {
87 this.prevNodes[itemsLength - 1] = k;
88 a = tmp;
89 }
90 }
91 console.log("~~~", lineWidth);
92 console.log(items[itemsLength - 2]);
93 return a;
94 }
95 /**
96 * check the total cost item[0..j].
97 * @param items
98 * @param i
99 * @param lineWidth
100 */
101 totalCostAux(items, j, lineWidth) {
102 if (this.totalCostAuxStorage[j] !== null) {
103 return this.totalCostAuxStorage[j];
104 }
105 let rawLineCost = this.lineCost(items, 0, j, lineWidth);
106 if (rawLineCost != Infinity) {
107 this.totalCostAuxStorage[j] = rawLineCost ** 3.0;
108 return rawLineCost ** 3.0;
109 }
110 else {
111 var returnCost = Infinity;
112 for (var k = 0; k < j; k++) {
113 let tmp = this.totalCostAux(items, k, lineWidth) + this.lineCost(items, k + 1, j, lineWidth) ** 3.0;
114 if (returnCost > tmp) {
115 this.prevNodes[j] = k;
116 returnCost = tmp;
117 }
118 }
119 this.totalCostAuxStorage[j] = returnCost;
120 return returnCost;
121 }
122 return returnCost;
123 }
124 /**
125 * check the line cost of a line containing items[i..j]
126 * @param items items of box
127 * @param i beginning (excluded)
128 * @param j end of the line
129 * @param lineWidth line width
130 */
131 lineCost(items, i, j, lineWidth) {
132 if (this.lineCostStorage[i] !== null && this.lineCostStorage[i][j] !== null) {
133 return this.lineCostStorage[i][j];
134 }
135 if (!this.isBreakPoint(items[j])) {
136 this.lineCostStorage[i][j] = Infinity;
137 return Infinity;
138 }
139 else {
140 var tmpItemWidth = 0;
141 for (var k = i; k < j; k++) {
142 tmpItemWidth += this.origWidth(items[k]);
143 }
144 tmpItemWidth += this.newLineWidth(items[j]);
145 if (tmpItemWidth > lineWidth) {
146 this.lineCostStorage[i][j] = Infinity;
147 return Infinity;
148 }
149 else {
150 let returnValue = (lineWidth - tmpItemWidth);
151 this.lineCostStorage[i][j] = returnValue;
152 return returnValue;
153 }
154 }
155 }
156 }
157 exports.BreakLineAlgorithm = BreakLineAlgorithm;