]> git.kianting.info Git - clo/blob - src/libclo/breakLines.js
14a7836178190690f79c86f462067fa58022a4aa
[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 return a;
92 }
93 /**
94 * check the total cost item[0..j].
95 * @param items
96 * @param i
97 * @param lineWidth
98 */
99 totalCostAux(items, j, lineWidth) {
100 if (this.totalCostAuxStorage[j] !== null) {
101 return this.totalCostAuxStorage[j];
102 }
103 let rawLineCost = this.lineCost(items, 0, j, lineWidth);
104 if (rawLineCost != Infinity) {
105 this.totalCostAuxStorage[j] = rawLineCost ** 3.0;
106 return rawLineCost ** 3.0;
107 }
108 else {
109 var returnCost = Infinity;
110 for (var k = 0; k < j; k++) {
111 let tmp = this.totalCostAux(items, k, lineWidth) + this.lineCost(items, k + 1, j, lineWidth) ** 3.0;
112 if (returnCost > tmp) {
113 this.prevNodes[j] = k;
114 returnCost = tmp;
115 }
116 }
117 this.totalCostAuxStorage[j] = returnCost;
118 return returnCost;
119 }
120 }
121 /**
122 * check the line cost of a line containing items[i..j]
123 * @param items items of box
124 * @param i beginning (excluded)
125 * @param j end of the line
126 * @param lineWidth line width
127 */
128 lineCost(items, i, j, lineWidth) {
129 if (this.lineCostStorage[i][j] !== null) {
130 console.log("AA");
131 return this.lineCostStorage[i][j];
132 }
133 if (!this.isBreakPoint(items[j])) {
134 this.lineCostStorage[i][j] = Infinity;
135 return Infinity;
136 }
137 else {
138 var tmpItemWidth = 0;
139 for (var k = i; k < j; k++) {
140 tmpItemWidth += this.origWidth(items[k]);
141 }
142 tmpItemWidth += this.newLineWidth(items[j]);
143 if (tmpItemWidth > lineWidth) {
144 this.lineCostStorage[i][j] = Infinity;
145 return Infinity;
146 }
147 else {
148 let returnValue = (lineWidth - tmpItemWidth);
149 this.lineCostStorage[i][j] = returnValue;
150 return returnValue;
151 }
152 }
153 }
154 }
155 exports.BreakLineAlgorithm = BreakLineAlgorithm;