]>
git.kianting.info Git - clo/blob - src/libclo/breakLines.ts
2 * Algorithms and functions for LineBreaking
4 import { join
} from
"path";
5 import {BreakPoint
, BoxesItem
, HGlue
, CharBox
} from
"./index.js";
6 import { listenerCount
} from
"process";
7 import { unwatchFile
} from
"fs";
9 * Algorithms in LATEX-like language
12 export class BreakLineAlgorithm
{
14 lineCostStorage
: number[][];
15 totalCostAuxStorage
: number[];
22 this.totalCostAuxStorage
= [];
23 this.lineCostStorage
= [[]];
26 /**check if a boeitem is BreakPoint Type */
27 isBreakPoint (item
: any) : item
is BreakPoint
{
28 return (item
as BreakPoint
).newLined
!== undefined;
31 /**check if a boeitem is HGlue Type */
32 isHGlue (item
: any) : item
is HGlue
{
33 return (item
as HGlue
).stretchFactor
!== undefined;
37 /** measuring original advance width */
38 origWidth(item
: BoxesItem
) : number{
39 if (this.isBreakPoint(item
)){
40 return this.origWidth(item
.original
);
41 }else if(Array.isArray(item
)){
42 return item
.map((x
)=>this.origWidth(x
))
43 .reduce((acc
, current
) => acc
+ current
,
45 }else if(this.isHGlue(item
)){
53 /**segement node of one paragraph into lines.
54 * @args items: nodes of a line
55 * @args linewidth: the line width
56 * @returns segmented nodes into lines
58 segmentedNodes(items
: BoxesItem
[], lineWidth
: number) : BoxesItem
[][]{
60 let lineWidthFixed
= lineWidth
;
61 this.totalCost(items
,lineWidthFixed
);
62 let nodeList
= this.generateBreakLineNodeList();
67 for(var i
=0; i
<nodeList
.length
; i
++){
68 res
.push(items
.slice(low
+1, up
+1));
78 /**genrate the list of point of breaking line. it returns a correct list ascending*/
79 generateBreakLineNodeList() : number[]{
80 let res
: number[] = [];
81 var pointer
= this.prevNodes
.length
-1;
82 while (this.prevNodes
[pointer
] !== undefined){
84 pointer
= this.prevNodes
[pointer
];
89 /** measuring new-line triggered advance width */
90 newLineWidth(item
: BoxesItem
) : number{
91 if (this.isBreakPoint(item
)){
92 return this.origWidth(item
.newLined
);
94 // impossible to make a new line
99 * check all the total cost of paragraphes of the segnemt
101 totalCost(items
: BoxesItem
[], lineWidth
: number) : number{
102 let lineWidthFixed
= lineWidth
* 0.75;
103 let itemsLength
= items
.length
;
104 this.lineCostStorage
= Array(itemsLength
);
105 this.prevNodes
= Array(itemsLength
).fill(null);
108 for (var i
=0; i
<itemsLength
; i
++){
109 this.lineCostStorage
[i
] = Array(itemsLength
).fill(null);
112 this.totalCostAuxStorage
= Array(itemsLength
).fill(null);
115 for(var k
=itemsLength
-2; this.lineCost(items
, k
+1,itemsLength
-1, lineWidthFixed
) < Infinity; k
--){
117 let tmp
= this.totalCostAux(items
, k
, lineWidthFixed
);
120 this.prevNodes
[itemsLength
-1] = k
130 * check the total cost item[0..j].
135 totalCostAux(items
: BoxesItem
[], j
: number, lineWidth
: number): number{
137 if (this.totalCostAuxStorage
[j
] !== null){
138 return this.totalCostAuxStorage
[j
];
141 let rawLineCost
= this.lineCost(items
, 0, j
, lineWidth
);
142 if (rawLineCost
!= Infinity){
143 this.totalCostAuxStorage
[j
] = rawLineCost
**3.0;
144 return rawLineCost
**3.0;
146 var returnCost
= Infinity;
147 for(var k
=0; k
<j
; k
++){
148 let tmp
= this.totalCostAux(items
, k
, lineWidth
) + this.lineCost(items
, k
+1,j
, lineWidth
)**3.0;
149 if (returnCost
> tmp
){
150 this.prevNodes
[j
] = k
;
154 this.totalCostAuxStorage
[j
] = returnCost
;
166 * check the line cost of a line containing items[i..j]
167 * @param items items of box
168 * @param i beginning (excluded)
169 * @param j end of the line
170 * @param lineWidth line width
172 lineCost(items
: BoxesItem
[], i
: number, j
: number, lineWidth
: number) : number{
173 if (this.lineCostStorage
[i
][j
] !== null){
175 return this.lineCostStorage
[i
][j
];
178 if (!this.isBreakPoint(items
[j
])){
179 this.lineCostStorage
[i
][j
] = Infinity;
182 var tmpItemWidth
= 0;
183 for (var k
= i
; k
<j
; k
++){
184 tmpItemWidth
+= this.origWidth(items
[k
]);
187 tmpItemWidth
+= this.newLineWidth(items
[j
]);
189 if (tmpItemWidth
> lineWidth
){
190 this.lineCostStorage
[i
][j
] = Infinity;
193 let returnValue
= (lineWidth
- tmpItemWidth
);
194 this.lineCostStorage
[i
][j
] = returnValue
;