231120 fix the algorithm

This commit is contained in:
Tan, Kian-ting 2023-11-20 21:48:10 +08:00
parent e9819c8bc2
commit ea033498d7
8 changed files with 65 additions and 51 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ node_modules
.vscode
activate.sh
docs/.nojekyll
debug.log

7
b.clo
View file

@ -1,4 +1,5 @@
---
In the beginning was the Word, and the Word was with God, and the Word was God. The same was in the beginning with God. All things were made by him; and without him was not any thing made that was made.
In him was life; and the life was the light of men.
And the light shineth in darkness; and the darkness comprehended it not.
In the beginning was the Word, and the Word was with God, and the Word was God. The same was
in the beginning with God. All things were made by him; and without him was not any thing made that
was made. In him was life; and the life was the light of men. And the light shineth in darkness; and
the darkness comprehended it not. There was a man sent from God, whose name was John.

6
b.js
View file

@ -9,9 +9,9 @@ let clo = new cloLib.Clo();
/* CLO: beginning of middle part*/
clo.mainStream = /* CLO: end of middle part*/
[`In`, ` `, `the`, ` `, `beginning`, ` `, `was`, ` `, `the`, ` `, `Word,`, ` `, `and`, ` `, `the`, ` `, `Word`, ` `, `was`, ` `, `with`, ` `, `God,`, ` `, `and`, ` `, `the`, ` `, `Word`, ` `, `was`, ` `, `God.`, ` `, `The`, ` `, `same`, ` `, `was`, ` `, `in`, ` `, `the`, ` `, `beginning`, ` `, `with`, ` `, `God.`, ` `, `All`, ` `, `things`, ` `, `were`, ` `, `made`, ` `, `by`, ` `, `him`, `;`, ` `, `and`, ` `, `without`, ` `, `him`, ` `, `was`, ` `, `not`, ` `, `any`, ` `, `thing`, ` `, `made`, ` `, `that`, ` `, `was`, ` `, `made.`, `
`, `In`, ` `, `him`, ` `, `was`, ` `, `life`, `;`, ` `, `and`, ` `, `the`, ` `, `life`, ` `, `was`, ` `, `the`, ` `, `light`, ` `, `of`, ` `, `men.`, `
`, `And`, ` `, `the`, ` `, `light`, ` `, `shineth`, ` `, `in`, ` `, `darkness`, `;`, ` `, `and`, ` `, `the`, ` `, `darkness`, ` `, `comprehended`, ` `, `it`, ` `, `not.`, ` `];
[`In`, ` `, `the`, ` `, `beginning`, ` `, `was`, ` `, `the`, ` `, `Word,`, ` `, `and`, ` `, `the`, ` `, `Word`, ` `, `was`, ` `, `with`, ` `, `God,`, ` `, `and`, ` `, `the`, ` `, `Word`, ` `, `was`, ` `, `God.`, ` `, `The`, ` `, `same`, ` `, `was`, `
`, `in`, ` `, `the`, ` `, `beginning`, ` `, `with`, ` `, `God.`, ` `, `All`, ` `, `things`, ` `, `were`, ` `, `made`, ` `, `by`, ` `, `him`, `;`, ` `, `and`, ` `, `without`, ` `, `him`, ` `, `was`, ` `, `not`, ` `, `any`, ` `, `thing`, ` `, `made`, ` `, `that`, `
`, `was`, ` `, `made.`, ` `, `In`, ` `, `him`, ` `, `was`, ` `, `life`, `;`, ` `, `and`, ` `, `the`, ` `, `life`, ` `, `was`, ` `, `the`, ` `, `light`, ` `, `of`, ` `, `men.`, ` `, `And`, ` `, `the`, ` `, `light`, ` `, `shineth`, ` `, `in`, ` `, `darkness`, `;`, ` `, `and`, ` `, `the`, ` `, `darkness`, ` `, `comprehended`, ` `, `it`, ` `, `not.`, ["hglue", "10000"], " "];
/* CLO: beginning of end part*/
clo.generatePdf();
/*CLO : end of end part*/

Binary file not shown.

View file

@ -35,10 +35,9 @@ class BreakLineAlgorithm {
}
}
segmentedNodes(items, lineWidth) {
let lineWidthFixed = lineWidth * 0.75;
let lineWidthFixed = lineWidth;
this.totalCost(items, lineWidthFixed);
let nodeList = this.generateBreakLineNodeList();
console.log("~~~", nodeList);
let res = [];
let low = -1;
let up = nodeList[0];
@ -47,7 +46,6 @@ class BreakLineAlgorithm {
low = nodeList[i];
up = nodeList[i + 1];
}
console.log("===", res.length);
return res;
}
/**genrate the list of point of breaking line. it returns a correct list ascending*/
@ -74,6 +72,7 @@ class BreakLineAlgorithm {
* check all the total cost of paragraphes of the segnemt
*/
totalCost(items, lineWidth) {
let lineWidthFixed = lineWidth * 0.75;
let itemsLength = items.length;
this.lineCostStorage = Array(itemsLength);
this.prevNodes = Array(itemsLength).fill(null);
@ -81,7 +80,16 @@ class BreakLineAlgorithm {
this.lineCostStorage[i] = Array(itemsLength).fill(null);
}
this.totalCostAuxStorage = Array(itemsLength).fill(null);
let a = this.totalCostAux(items, itemsLength - 1, lineWidth);
let a = Infinity;
for (var k = itemsLength - 2; this.lineCost(items, k + 1, itemsLength - 1, lineWidthFixed) < Infinity; k--) {
let tmp = this.totalCostAux(items, k, lineWidthFixed);
if (a > tmp) {
this.prevNodes[itemsLength - 1] = k;
a = tmp;
}
}
console.log("~~~", lineWidth);
console.log(items[itemsLength - 2]);
return a;
}
/**
@ -96,13 +104,13 @@ class BreakLineAlgorithm {
}
let rawLineCost = this.lineCost(items, 0, j, lineWidth);
if (rawLineCost != Infinity) {
this.totalCostAuxStorage[j] = rawLineCost;
return rawLineCost;
this.totalCostAuxStorage[j] = rawLineCost ** 3.0;
return rawLineCost ** 3.0;
}
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);
let tmp = this.totalCostAux(items, k, lineWidth) + this.lineCost(items, k + 1, j, lineWidth) ** 3.0;
if (returnCost > tmp) {
this.prevNodes[j] = k;
returnCost = tmp;
@ -139,7 +147,7 @@ class BreakLineAlgorithm {
return Infinity;
}
else {
let returnValue = (lineWidth - tmpItemWidth) ** 3.0;
let returnValue = (lineWidth - tmpItemWidth);
this.lineCostStorage[i][j] = returnValue;
return returnValue;
}

View file

@ -2,7 +2,7 @@
* Algorithms and functions for LineBreaking
*/
import { join } from "path";
import {BreakPoint, BoxesItem, HGlue} from "./index.js";
import {BreakPoint, BoxesItem, HGlue, CharBox} from "./index.js";
import { listenerCount } from "process";
import { unwatchFile } from "fs";
/**
@ -51,10 +51,9 @@ export class BreakLineAlgorithm {
}
segmentedNodes(items : BoxesItem[], lineWidth : number) : BoxesItem[][]{
let lineWidthFixed = lineWidth * 0.75;
let lineWidthFixed = lineWidth;
this.totalCost(items ,lineWidthFixed);
let nodeList = this.generateBreakLineNodeList();
console.log("~~~", nodeList);
let res = [];
let low = -1;
let up = nodeList[0];
@ -65,7 +64,6 @@ export class BreakLineAlgorithm {
up = nodeList[i+1];
}
console.log("===", res.length);
return res;
}
@ -93,7 +91,7 @@ export class BreakLineAlgorithm {
* check all the total cost of paragraphes of the segnemt
*/
totalCost(items : BoxesItem[], lineWidth: number) : number{
let lineWidthFixed = lineWidth * 0.75;
let itemsLength = items.length;
this.lineCostStorage = Array(itemsLength);
this.prevNodes = Array(itemsLength).fill(null);
@ -104,7 +102,19 @@ export class BreakLineAlgorithm {
}
this.totalCostAuxStorage = Array(itemsLength).fill(null);
let a = this.totalCostAux(items, itemsLength-1, lineWidth);
let a = Infinity;
for(var k=itemsLength-2; this.lineCost(items, k+1,itemsLength-1, lineWidthFixed) < Infinity; k--){
let tmp = this.totalCostAux(items, k, lineWidthFixed);
if (a > tmp){
this.prevNodes[itemsLength-1] = k
a = tmp;
}
}
console.log("~~~", lineWidth);
console.log((<CharBox>items[itemsLength-2]));
return a;
}
@ -123,12 +133,12 @@ export class BreakLineAlgorithm {
let rawLineCost = this.lineCost(items, 0, j, lineWidth);
if (rawLineCost != Infinity){
this.totalCostAuxStorage[j] = rawLineCost;
return rawLineCost;
this.totalCostAuxStorage[j] = rawLineCost**3.0;
return rawLineCost**3.0;
}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);
let tmp = this.totalCostAux(items, k, lineWidth) + this.lineCost(items, k+1,j, lineWidth)**3.0;
if (returnCost > tmp){
this.prevNodes[j] = k;
returnCost = tmp;
@ -173,7 +183,7 @@ export class BreakLineAlgorithm {
this.lineCostStorage[i][j] = Infinity;
return Infinity;
}else{
let returnValue = (lineWidth - tmpItemWidth)**3.0;
let returnValue = (lineWidth - tmpItemWidth);
this.lineCostStorage[i][j] = returnValue;
return returnValue;
}

View file

@ -70,8 +70,8 @@ exports.defaultFrameStyle = {
direction: Direction.TTB,
baseLineskip: ptToPx(15),
textStyle: exports.defaultTextStyle,
x: exports.A4_IN_PX.width * 0.10 * 0.75,
y: exports.A4_IN_PX.height * 0.10 * 0.75,
x: exports.A4_IN_PX.width * 0.10,
y: exports.A4_IN_PX.height * 0.10,
width: exports.A4_IN_PX.width * 0.80,
height: exports.A4_IN_PX.height * 0.80,
content: null,
@ -277,8 +277,8 @@ function calculateTextWidthHeightAux(element, style) {
y: null,
textStyle: style,
direction: Direction.LTR,
width: (runGlyphsItem.advanceWidth) * (style.size) * 0.75 / 1000,
height: (runGlyphsItem.bbox.maxY - runGlyphsItem.bbox.minY) * (style.size) * 0.75 / 1000,
width: (runGlyphsItem.advanceWidth) * (style.size) / 1000 * 0.75,
height: (runGlyphsItem.bbox.maxY - runGlyphsItem.bbox.minY) * (style.size) / 1000 * 0.75,
content: element[j],
minX: runGlyphsItem.bbox.minX,
maxX: runGlyphsItem.bbox.maxX,
@ -365,7 +365,6 @@ class Clo {
// TODO
//console.log(breakLineAlgorithms.totalCost(a,70));
let segmentedNodes = breakLineAlgorithms.segmentedNodes(a, this.attrs.defaultFrameStyle.width);
console.log(this.attrs.defaultFrameStyle.width);
let segmentedNodesToBox = this.segmentedNodesToFrameBox(segmentedNodes, this.attrs.defaultFrameStyle);
let boxesFixed = this.fixenBoxesPosition(segmentedNodesToBox);
// generate pdf7
@ -389,7 +388,7 @@ class Clo {
else {
doc
.font(fontInfo.path)
.fontSize(box.textStyle.size * 0.75);
.fontSize(box.textStyle.size * 0.75); // 0.75 must added!
}
if (box.textStyle.color !== undefined) {
doc.fill(box.textStyle.color);
@ -400,7 +399,6 @@ class Clo {
}
}
else if (box.content !== null) {
console.log(box.content, box.x, box.y);
yield doc.text(box.content, (box.x !== null ? box.x : undefined), (box.y !== null ? box.y : undefined));
}
}
@ -461,7 +459,6 @@ class Clo {
* @returns the fixed boxes
*/
fixenBoxesPosition(box) {
console.log("~~~~~", box);
var currX = (box.x !== null ? box.x : 0); // current x
var currY = (box.y !== null ? box.y : 0); // current y
if (Array.isArray(box.content)) {
@ -497,8 +494,8 @@ class Clo {
let baseLineskip = frame.baseLineskip;
let boxArrayEmpty = [];
let bigBox = {
x: frame.x,
y: frame.y,
x: (frame.x !== null ? frame.x * 0.75 : null),
y: (frame.y !== null ? frame.y * 0.75 : null),
textStyle: frame.textStyle,
direction: frame.direction,
width: frame.width,
@ -562,7 +559,6 @@ class Clo {
} })
.reduce((acc, cur) => acc + cur, 0);
let offset = frame.width * 0.75 - glueRemovedWidth;
console.log("OFFSET", offset);
var res = [];
for (var i = 0; i < nodeLine.length; i++) {
var ele = nodeLine[i];
@ -572,6 +568,7 @@ class Clo {
y: null,
textStyle: null,
direction: frame.directionInsideLine,
//width : 0, // ragged
width: ele.stretchFactor / sumStretchFactor * offset,
height: 0,
content: "",

View file

@ -58,11 +58,11 @@ export interface CharBox extends Box{
/**
* a basic Box
* - x :
* - y :
* - x : pt
* - y : pt
* - textStyle :
* - direction :
* - width : x_advance
* - width : x_advance pt
* - content :
*/
export interface Box{
@ -94,8 +94,8 @@ export const defaultFrameStyle : FrameBox = {
direction : Direction.TTB,
baseLineskip : ptToPx(15),
textStyle : defaultTextStyle,
x : A4_IN_PX.width * 0.10 * 0.75,
y : A4_IN_PX.height * 0.10 * 0.75,
x : A4_IN_PX.width * 0.10 ,
y : A4_IN_PX.height * 0.10 ,
width : A4_IN_PX.width * 0.80 ,
height : A4_IN_PX.height * 0.80 ,
content : null,
@ -328,8 +328,8 @@ export async function calculateTextWidthHeightAux(element : tkTree, style : Text
y : null,
textStyle : style,
direction : Direction.LTR,
width : (runGlyphsItem.advanceWidth)*(style.size)*0.75/1000,
height : (runGlyphsItem.bbox.maxY - runGlyphsItem.bbox.minY)*(style.size)*0.75/1000,
width : (runGlyphsItem.advanceWidth)*(style.size)/1000 * 0.75, // in pt
height : (runGlyphsItem.bbox.maxY - runGlyphsItem.bbox.minY)*(style.size)/1000 * 0.75, // in pt
content : element[j],
minX : runGlyphsItem.bbox.minX,
maxX : runGlyphsItem.bbox.maxX,
@ -443,7 +443,6 @@ export class Clo{
//console.log(breakLineAlgorithms.totalCost(a,70));
let segmentedNodes = breakLineAlgorithms.segmentedNodes(a, this.attrs.defaultFrameStyle.width);
console.log(this.attrs.defaultFrameStyle.width);
let segmentedNodesToBox =
this.segmentedNodesToFrameBox(segmentedNodes, <FrameBox>this.attrs.defaultFrameStyle);
@ -477,7 +476,7 @@ export class Clo{
else{
doc
.font(fontInfo.path)
.fontSize(box.textStyle.size*0.75);
.fontSize(box.textStyle.size * 0.75); // 0.75 must added!
}
if (box.textStyle.color !== undefined){
@ -490,7 +489,6 @@ export class Clo{
doc = await this.putText(doc, box.content[k]);
}
}else if (box.content !== null){
console.log(box.content, box.x, box.y);
await doc.text(box.content,
(box.x!==null? box.x: undefined),
(box.y!==null? box.y: undefined));
@ -560,7 +558,6 @@ export class Clo{
* @returns the fixed boxes
*/
fixenBoxesPosition(box : Box) : Box{
console.log("~~~~~", box);
var currX : number = (box.x!==null?box.x:0); // current x
var currY : number =(box.y!==null?box.y:0); // current y
if (Array.isArray(box.content)){
@ -602,8 +599,8 @@ export class Clo{
let baseLineskip = frame.baseLineskip;
let boxArrayEmpty : Box[] = [];
let bigBox : Box = {
x : frame.x,
y : frame.y,
x : (frame.x !==null? frame.x * 0.75 : null),
y : (frame.y !==null? frame.y * 0.75 : null),
textStyle : frame.textStyle,
direction : frame.direction,
width : frame.width,
@ -664,7 +661,6 @@ export class Clo{
let glueRemovedWidth = glueRemoved.map((x)=>{if("width" in x){ return x.width} else{return 0;}})
.reduce((acc, cur)=>acc+cur , 0);
let offset = frame.width * 0.75 - glueRemovedWidth;
console.log("OFFSET", offset);
var res = [];
for (var i=0; i<nodeLine.length; i++){
var ele = nodeLine[i];
@ -674,6 +670,7 @@ export class Clo{
y : null,
textStyle : null,
direction : frame.directionInsideLine,
//width : 0, // ragged
width : ele.stretchFactor / sumStretchFactor * offset,
height : 0,
content : "",