From: Tan Kian-ting Date: Mon, 20 Nov 2023 13:48:10 +0000 (+0800) Subject: 231120 fix the algorithm X-Git-Url: https://git.kianting.info/?a=commitdiff_plain;h=ea033498d79b3a84b16e15ff2a218ac5ef5f70b5;p=clo 231120 fix the algorithm --- diff --git a/.gitignore b/.gitignore index 68ef560..56f44a9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules .vscode activate.sh docs/.nojekyll +debug.log diff --git a/b.clo b/b.clo index ca06b07..293bb5d 100644 --- a/b.clo +++ b/b.clo @@ -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. \ No newline at end of file +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. \ No newline at end of file diff --git a/b.js b/b.js index 5f90185..8e28a83 100644 --- a/b.js +++ b/b.js @@ -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*/ diff --git a/output.pdf b/output.pdf index 054d885..bc6726d 100644 Binary files a/output.pdf and b/output.pdf differ diff --git a/src/libclo/breakLines.js b/src/libclo/breakLines.js index 9367d53..f194aa5 100644 --- a/src/libclo/breakLines.js +++ b/src/libclo/breakLines.js @@ -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; } diff --git a/src/libclo/breakLines.ts b/src/libclo/breakLines.ts index 45ffe65..fba0282 100644 --- a/src/libclo/breakLines.ts +++ b/src/libclo/breakLines.ts @@ -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((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 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; } diff --git a/src/libclo/index.js b/src/libclo/index.js index 665b359..2840b3d 100644 --- a/src/libclo/index.js +++ b/src/libclo/index.js @@ -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: "", diff --git a/src/libclo/index.ts b/src/libclo/index.ts index fa8c660..e5c2108 100644 --- a/src/libclo/index.ts +++ b/src/libclo/index.ts @@ -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, this.attrs.defaultFrameStyle); @@ -473,11 +472,11 @@ export class Clo{ if (fontInfo.path.match(/\.ttc$/g)){ doc .font(fontInfo.path, fontInfo.psName) - .fontSize(box.textStyle.size*0.75);} + .fontSize(box.textStyle.size * 0.75);} 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,12 +599,12 @@ 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, - height : frame.height, + height :frame.height, content : boxArrayEmpty, } @@ -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