fix the algorithms, and try to add a bigframe initially.

This commit is contained in:
Tan, Kian-ting 2023-11-13 23:45:02 +08:00
parent a4f79a3761
commit f12842e5a4
80 changed files with 2233 additions and 437 deletions

View file

@ -35,6 +35,7 @@
- 20231029-30: hyphenating for english.
- 20231105-06: 利用fontkit算文字的對應px寬度 initially pushed.
- 20231109-10: Keng-kái oa̍h-chōa ián-sǹg-hoat.
- 20231113: the algorithm is basically fixed, and make a `bigFrame` to prepare for convert to boxes and positions.
## 之後的做法
- 先做一個前處理註冊器,註冊下列的前處理

2
b.clo
View file

@ -1,2 +1,2 @@
---
The book of the generation of Jesus Christ, the son of David,
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.

View file

@ -1 +1 @@
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA42XW0/bMBSA/0ue0TYYsI230gZWoGnUZAMJocqkbuPVsaPEKa2m/fe5iZM6t+M8leZ8/hpfzvHh9a8l8F5YN1aA2A5ZZ1aMRCi/RnyVUZx+zh9/CkVEZWxL2Mq6uTizgpDQVYKZdfNaCXz54YkDxScJZllUKqpwXfb931nN8IzJJhT9iiLe7xhTfhpMmMDJGgXVPGS0MZer6/rgMY8iJCOgQ0GQ6o6z5mq0TBUDidYScqXA9RwUYReRBDC2YUjtTu4mPMgizLQFF4e40mlAw/Plx7fzq4vG3nkiwSj6xUiPrs6YjOtydXx+/POkXGcsEIQzfdIaWPdeX2rKOBPHd+hXKaCleNMk8hnetxMlfzwoUUJM4wlOg5NjhxKC3jWLIuq6r/rqxAmX256Oks2uazqFR4PAKVHyHuh5U86peD5oUhOS4Py3m6mrHFV8YOoGFKXp6RVaiXt+oQ+95fvOrFCjZRjM1UQmi0FRMpBndLmcOkv3pWtjlaZEgJ0N/mx3t5QH23TKFnijn7WWrsUavDkjC4ScHTNodRSwrvAaZVTky9Oody1tizV7Oy6VPm3PBVOzhoc4xOyOJ7Wzdkqb8sBrGFBOCszf+gnGRluBQcVJ+NzdA54CAAxpTIkYPzz+BiQVA3jEB19gkSUs9bmDPyhh0PQ6aLDYxChJcdIuNsXzYa0G32L2SPRruig2ylHF+4uNaOxacU+p8aJjr9oX1Hju+Lbjd51M5VEEcCCnM3e+gBQFYDTYttFh20aLZ5R4gMOZ+8sRNJcCMBqWvv1i1uQU4HIX83tAcgwDoz37fgbvrSJAx2w6nj/NHdCiGMBD8V7Pl5YjjwPjeSZkX2Pr2dJyVIzR8xMjs+gIGU0zslp1F/aaq8AAG4pjeji25Li7S1Q2HQOKn8JkAzDElmMm2zSKeWKUFdQwVzpMlppsDhej3pZY91WgyeiiAW+XQ4NMz0SE8hgMW8H2CNNveHgz5NQozGyLyJhTvQfu8ynQaIxlD+o8GX0FZrIN2WjDHhOm/kXyeV/Xo2wNEmo3ZNjnDx4gK5GOxuLtPxjWUt7DEAAA"
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA52YXXObOBRA/4ufM9s223Z38+Y4JHEbYyZm28xkOh4Fy0a1kBghUrs7/e8rQIBAcMX0KQn36OgD6V6R5/9mEp/k7GoWIfaKZhezFMlY/ZnwXU5x9qZ8/EcsE6piR8J2s6vLi1kUE7oTmM2unhvBLWdyI88UtxLM8qRWNOGu7O9fF40hVD++YnKI5bCijY87FpS3jQmTWOxR1MxDRXtz+fCx23jBkwSpCOjQEKQqxtpbDcvUMJBor9YtUIJg46MEB4gIwGjDkDq4ub3hUZ5gZiy4PKeNzgB6nrf//PXuw6U1X4FR8i8jI7ou4zLu6w0T8uLXVrnPWSQJZ+akDbDr/fjeUKa5LMYwrtKApfhmSGIk9i/5z5/2Wakjk45LDYc4GxxQKzNAcGDqGT7ZoyofTxsSpukNzqLW8YoEQS+GRRNd3Z/ma0sFV/sxm4vD69C0Ko8BgVOi5CUyD3Q9p+r5pEndEIHLvvs5RTua+MScElGUZe0QrIzy7tJses1Pg8dVt1Zh6IBeq7NyDDgxd/+ApKHA3Kb2kWM0GoEst0LlFYemZiDP/R3Nh1OjlpQAuDb8hLOlxEk/17RLW8VdeWb+frv0t8HT0K7XrhoBtn30/fh6TXl0zJbsER/Mg2jpLNbhLRmV1tUaMYfWRAHrDu9RTmX5pnpVytJarNs7UPzGtCM1sLsGiEY5RRKXFwCyk/F975bQ5pd6LUaaAMVhrMk8P/1GR6oV0NeeUPWGvCSVZ1UQCTsAPVgs4I3PaYzZLRedlGUpTcxpC4+hwNhpqzCo+MqQB9BSVgBgyNIiQ4S8THhpNy1aNhsGzZTIxafPX0ChZgCP/MEfscwFUx37+AclDFq4AXpCNXzzUszoQcHZWGHctsikGnld43N64ILI2Eiq3Xpnmu1WdiU0h58ikWFhj7l6PmmgIT9i9pmY9/OqmGtHEx8v5rK3nauiodvLgU1sV4zF2g89PxxKbtqjCSCnLVfB+hFSVIDT4HlOh+c5LRunZAM4/HW4nUNzqQCnYRt6T25NSQGu4HF9B0iKMNB6492t4HerCdCxWi7WD2sftGgG8FB8Ms+L5SjjQHueS/VB45mnxXI0jNNzj5FbVEBO04rsdsN3g46rwgAbSlN6Lr7F8XAl0DYTA3K3xtRNdIqtxFy2ZZJy4ZRV1DRXNk2WuWw+l/PRb2HT14AuY4AmjK6EJpm+qnqitsG0FbRbuPrY4MOUXaMxty0hC07Nb8wxnwadxuL24j84fRXmsk150Y53TJj+30jIx66D2tYjoduSCof80waQ1Qh4L0p3+xViJC3v4QP3CzPcq+2/vv0PRTFWxwIVAAA="

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,95 +1,149 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.totalCost = void 0;
exports.BreakLineAlgorithm = void 0;
/**
* Algorithms in LATEX language
TotalCost(i) = min_{j}~TotalCost(j) + LineCost(j, i)~~~~j=0, 1, ..., i-1
LineCost(j, i)= \begin{cases}
\infty ~~~ if~~LineWidth - \sum_{k=j+1}^{i-1} OrigWidth(item[k]) - newLineWidth(item[i]) < 0 \\
\infty~~if~~NOT~~breakable(item[i]) \\
(LineWidth - \sum_{k=j+1}^{i-1} OrigWidth(item[k]) - newLineWidth(item[i]))^3 ~~elsewhere
\end{cases} */
/**check if a boeitem is BreakPoint Type */
function isBreakPoint(item) {
return item.newLined !== undefined;
}
/**check if a boeitem is BreakPoint Type */
function isHGlue(item) {
return item.stretchFactor !== undefined;
}
/** measuring original advance width */
function origWidth(item) {
if (isBreakPoint(item)) {
console.log(item);
return origWidth(item.original);
}
else if (Array.isArray(item)) {
return item.map((x) => origWidth(x))
.reduce((acc, current) => acc + current, 0.0);
}
else if (isHGlue(item)) {
return 0.0;
}
else {
return item.width;
}
}
/** measuring new-line triggered advance width */
function newLineWidth(item) {
if (isBreakPoint(item)) {
return origWidth(item.newLined);
}
else {
// impossible to make a new line
return Infinity;
}
}
let lineCostStorage = new Object();
/**
* check the total cost item[0..j].
* @param items
* @param i
* @param lineWidth
* Algorithms in LATEX-like language
*/
function totalCost(items, j, lineWidth) {
if (j in lineCostStorage) {
return lineCostStorage[j];
class BreakLineAlgorithm {
constructor() {
this.prevNodes = [];
this.totalCostAuxStorage = [];
this.lineCostStorage = [[]];
}
var returnCost = Infinity;
for (var i = -1; i <= j; i++) {
// lineCost
let lCost = lineCost(items, i, j, lineWidth);
if (returnCost > lCost) {
returnCost = lCost;
/**check if a boeitem is BreakPoint Type */
isBreakPoint(item) {
return item.newLined !== undefined;
}
/**check if a boeitem is BreakPoint Type */
isHGlue(item) {
return item.stretchFactor !== undefined;
}
/** measuring original advance width */
origWidth(item) {
if (this.isBreakPoint(item)) {
return this.origWidth(item.original);
}
else if (Array.isArray(item)) {
return item.map((x) => this.origWidth(x))
.reduce((acc, current) => acc + current, 0.0);
}
else if (this.isHGlue(item)) {
return 0.0;
}
else {
return item.width;
}
}
lineCostStorage[j] = returnCost;
return returnCost;
}
exports.totalCost = totalCost;
/**
* check the line cost of a line containing items[i+1..j]
* @param items items of box
* @param i beginning (excluded)
* @param j end of the line
* @param lineWidth line width
*/
function lineCost(items, i, j, lineWidth) {
if (!isBreakPoint(items[j])) {
return Infinity;
}
else {
var tmpItemWidth = 0;
for (var k = i + 1; k < j; k++) {
tmpItemWidth += origWidth(items[k]);
segmentedNodes(items, lineWidth) {
this.totalCost(items, lineWidth);
let nodeList = this.generateBreakLineNodeList();
console.log("~~~", nodeList);
let res = [];
let low = -1;
let up = nodeList[0];
for (var i = 0; i < nodeList.length; i++) {
res.push(items.slice(low + 1, up + 1));
low = nodeList[i];
up = nodeList[i + 1];
}
tmpItemWidth += newLineWidth(items[j]);
if (tmpItemWidth > lineWidth) {
return res;
}
/**genrate the list of point of breaking line. it returns a correct list ascending*/
generateBreakLineNodeList() {
let res = [];
var pointer = this.prevNodes.length - 1;
while (this.prevNodes[pointer] !== undefined) {
res.push(pointer);
pointer = this.prevNodes[pointer];
}
return res.reverse();
}
/** measuring new-line triggered advance width */
newLineWidth(item) {
if (this.isBreakPoint(item)) {
return this.origWidth(item.newLined);
}
else {
// impossible to make a new line
return Infinity;
}
}
/**
* check all the total cost of paragraphes of the segnemt
*/
totalCost(items, lineWidth) {
let itemsLength = items.length;
this.lineCostStorage = Array(itemsLength);
this.prevNodes = Array(itemsLength).fill(null);
for (var i = 0; i < itemsLength; i++) {
this.lineCostStorage[i] = Array(itemsLength).fill(undefined);
}
this.totalCostAuxStorage = Array(itemsLength).fill(undefined);
console.log("===", itemsLength);
let a = this.totalCostAux(items, itemsLength - 1, lineWidth);
console.log(this.lineCostStorage);
return a;
}
/**
* check the total cost item[0..j].
* @param items
* @param i
* @param lineWidth
*/
totalCostAux(items, j, lineWidth) {
if (this.totalCostAuxStorage[j] !== undefined) {
return this.totalCostAuxStorage[j];
}
let rawLineCost = this.lineCost(items, 0, j, lineWidth);
if (rawLineCost != Infinity) {
this.totalCostAuxStorage[j] = rawLineCost;
return rawLineCost;
}
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);
if (returnCost > tmp) {
this.prevNodes[j] = k;
returnCost = tmp;
}
}
this.totalCostAuxStorage[j] = returnCost;
return returnCost;
}
return returnCost;
}
/**
* check the line cost of a line containing items[i..j]
* @param items items of box
* @param i beginning (excluded)
* @param j end of the line
* @param lineWidth line width
*/
lineCost(items, i, j, lineWidth) {
if (this.lineCostStorage[i] !== undefined && this.lineCostStorage[i][j] !== undefined) {
return this.lineCostStorage[i][j];
}
if (!this.isBreakPoint(items[j])) {
this.lineCostStorage[i][j] = Infinity;
return Infinity;
}
else {
return (lineWidth - tmpItemWidth) ** 3.0;
var tmpItemWidth = 0;
for (var k = i; k < j; k++) {
tmpItemWidth += this.origWidth(items[k]);
}
tmpItemWidth += this.newLineWidth(items[j]);
if (tmpItemWidth > lineWidth) {
this.lineCostStorage[i][j] = Infinity;
return Infinity;
}
else {
let returnValue = (lineWidth - tmpItemWidth) ** 3.0;
this.lineCostStorage[i][j] = returnValue;
return returnValue;
}
}
}
}
exports.BreakLineAlgorithm = BreakLineAlgorithm;

View file

@ -3,107 +3,182 @@
*/
import { join } from "path";
import {BreakPoint, BoxesItem, HGlue} from "./index.js";
import { listenerCount } from "process";
import { unwatchFile } from "fs";
/**
* Algorithms in LATEX language
TotalCost(i) = min_{j}~TotalCost(j) + LineCost(j, i)~~~~j=0, 1, ..., i-1
LineCost(j, i)= \begin{cases}
\infty ~~~ if~~LineWidth - \sum_{k=j+1}^{i-1} OrigWidth(item[k]) - newLineWidth(item[i]) < 0 \\
\infty~~if~~NOT~~breakable(item[i]) \\
(LineWidth - \sum_{k=j+1}^{i-1} OrigWidth(item[k]) - newLineWidth(item[i]))^3 ~~elsewhere
\end{cases} */
/**check if a boeitem is BreakPoint Type */
function isBreakPoint (item : any) : item is BreakPoint{
return (item as BreakPoint).newLined !== undefined;
}
/**check if a boeitem is BreakPoint Type */
function isHGlue (item : any) : item is HGlue{
return (item as HGlue).stretchFactor !== undefined;
}
/** measuring original advance width */
function origWidth(item : BoxesItem) : number{
if (isBreakPoint(item)){
console.log(item);
return origWidth(item.original);
}else if(Array.isArray(item)){
return item.map((x)=>origWidth(x))
.reduce((acc, current) => acc + current,
0.0,)
}else if(isHGlue(item)){
return 0.0;
}
else{
return item.width;
}
}
/** measuring new-line triggered advance width */
function newLineWidth(item : BoxesItem) : number{
if (isBreakPoint(item)){
return origWidth(item.newLined);
}else{
// impossible to make a new line
return Infinity;
}
}
let lineCostStorage : any = new Object();
/**
* check the total cost item[0..j].
* @param items
* @param i
* @param lineWidth
* Algorithms in LATEX-like language
*/
export function totalCost(items : BoxesItem[], j : number, lineWidth: number){
if (j in lineCostStorage){
return lineCostStorage[j];
}
var returnCost = Infinity;
export class BreakLineAlgorithm {
lineCostStorage : number[][];
totalCostAuxStorage : number[];
prevNodes : number[];
for(var i=-1; i<=j; i++){
// lineCost
let lCost = lineCost(items, i, j, lineWidth);
if (returnCost > lCost){
returnCost = lCost;
constructor(){
this.prevNodes = [];
this.totalCostAuxStorage = [];
this.lineCostStorage = [[]];
}
/**check if a boeitem is BreakPoint Type */
isBreakPoint (item : any) : item is BreakPoint{
return (item as BreakPoint).newLined !== undefined;
}
/**check if a boeitem is HGlue Type */
isHGlue (item : any) : item is HGlue{
return (item as HGlue).stretchFactor !== undefined;
}
/** measuring original advance width */
origWidth(item : BoxesItem) : number{
if (this.isBreakPoint(item)){
return this.origWidth(item.original);
}else if(Array.isArray(item)){
return item.map((x)=>this.origWidth(x))
.reduce((acc, current) => acc + current,
0.0,)
}else if(this.isHGlue(item)){
return 0.0;
}
else{
return item.width;
}
}
lineCostStorage[j] = returnCost;
return returnCost;
segmentedNodes(items : BoxesItem[], lineWidth : number) : BoxesItem[][]{
this.totalCost(items ,lineWidth);
let nodeList = this.generateBreakLineNodeList();
console.log("~~~", nodeList);
let res = [];
let low = -1;
let up = nodeList[0];
}
for(var i=0; i<nodeList.length; i++){
res.push(items.slice(low+1, up+1));
low = nodeList[i];
up = nodeList[i+1];
}
return res;
}
/**genrate the list of point of breaking line. it returns a correct list ascending*/
generateBreakLineNodeList() : number[]{
let res : number[] = [];
var pointer = this.prevNodes.length-1;
while (this.prevNodes[pointer] !== undefined){
res.push(pointer);
pointer = this.prevNodes[pointer];
}
return res.reverse();
}
/** measuring new-line triggered advance width */
newLineWidth(item : BoxesItem) : number{
if (this.isBreakPoint(item)){
return this.origWidth(item.newLined);
}else{
// impossible to make a new line
return Infinity;
}
}
/**
* check all the total cost of paragraphes of the segnemt
*/
totalCost(items : BoxesItem[], lineWidth: number) : number{
let itemsLength = items.length;
this.lineCostStorage = Array(itemsLength);
this.prevNodes = Array(itemsLength).fill(null);
/**
* check the line cost of a line containing items[i+1..j]
* @param items items of box
* @param i beginning (excluded)
* @param j end of the line
* @param lineWidth line width
*/
function lineCost(items : BoxesItem[], i : number, j : number, lineWidth: number){
if (!isBreakPoint(items[j])){
return Infinity;
}else{
var tmpItemWidth = 0;
for (var k = i+1; k<j; k++){
tmpItemWidth += origWidth(items[k]);
for (var i=0; i<itemsLength; i++){
this.lineCostStorage[i] = Array(itemsLength).fill(undefined);
}
tmpItemWidth += newLineWidth(items[j]);
this.totalCostAuxStorage = Array(itemsLength).fill(undefined);
console.log("===", itemsLength);
let a = this.totalCostAux(items, itemsLength-1, lineWidth);
console.log(this.lineCostStorage);
return a;
if (tmpItemWidth > lineWidth){
}
/**
* check the total cost item[0..j].
* @param items
* @param i
* @param lineWidth
*/
totalCostAux(items : BoxesItem[], j : number, lineWidth: number): number{
if (this.totalCostAuxStorage[j] !== undefined){
return this.totalCostAuxStorage[j];
}
let rawLineCost = this.lineCost(items, 0, j, lineWidth);
if (rawLineCost != Infinity){
this.totalCostAuxStorage[j] = rawLineCost;
return rawLineCost;
}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);
if (returnCost > tmp){
this.prevNodes[j] = k;
returnCost = tmp;
}
}
this.totalCostAuxStorage[j] = returnCost;
return returnCost;
}
return returnCost;
}
/**
* check the line cost of a line containing items[i..j]
* @param items items of box
* @param i beginning (excluded)
* @param j end of the line
* @param lineWidth line width
*/
lineCost(items : BoxesItem[], i : number, j : number, lineWidth: number) : number{
if (this.lineCostStorage[i] !== undefined && this.lineCostStorage[i][j] !== undefined){
return this.lineCostStorage[i][j];
}
if (!this.isBreakPoint(items[j])){
this.lineCostStorage[i][j] = Infinity;
return Infinity;
}else{
return (lineWidth - tmpItemWidth)**3.0;
var tmpItemWidth = 0;
for (var k = i; k<j; k++){
tmpItemWidth += this.origWidth(items[k]);
}
tmpItemWidth += this.newLineWidth(items[j]);
if (tmpItemWidth > lineWidth){
this.lineCostStorage[i][j] = Infinity;
return Infinity;
}else{
let returnValue = (lineWidth - tmpItemWidth)**3.0;
this.lineCostStorage[i][j] = returnValue;
return returnValue;
}
}
}
}

View file

@ -35,7 +35,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.Clo = exports.calculateTextWidthHeightAux = exports.calculateTextWidthHeight = exports.hyphenTkTree = exports.filterEmptyString = exports.spacesToBreakpoint = exports.hyphenForClo = exports.splitCJKV = exports.twoReturnsToNewline = exports.ptToPx = exports.cjkvRegexPattern = exports.cjkvBlocksInRegex = exports.defaultFrameStyle = exports.defaultTextStyle = exports.A4_IN_PX = exports.Direction = void 0;
const canva_1 = require("../canva");
const fontkit = __importStar(require("fontkit"));
const util = __importStar(require("node:util"));
const breakLines = __importStar(require("./breakLines"));
/**
* TYPES
@ -360,11 +359,127 @@ class Clo {
// generate the width and height of the stream
let defaultFontStyle = this.attrs["defaultFrameStyle"].textStyle;
let a = yield calculateTextWidthHeight(preprocessed, defaultFontStyle);
let breakLineAlgorithms = new breakLines.BreakLineAlgorithm();
// TODO
console.log(util.inspect(a, true, 100));
console.log(breakLines.totalCost(a, 3, 100));
//console.log(breakLineAlgorithms.totalCost(a,70));
let segmentedNodes = breakLineAlgorithms.segmentedNodes(a, 70);
console.log(this.segmentedNodesToFrameBox(segmentedNodes, this.attrs["defaultFrameStyle"]));
});
}
segmentedNodesToFrameBox(segmentedNodes, frame) {
let baseLineskip = frame.baseLineskip;
let boxArrayEmpty = [];
let bigBox = {
x: frame.x,
y: frame.y,
textStyle: frame.textStyle,
direction: frame.direction,
width: frame.width,
height: frame.height,
content: boxArrayEmpty,
};
var bigBoxContent = boxArrayEmpty;
let segmentedNodesFixed = segmentedNodes.map((x) => this.removeBreakPoints(x).flat());
let segmentedNodeUnglue = segmentedNodesFixed.map((x) => this.removeGlue(x, frame).flat());
for (var i = 0; i < segmentedNodesFixed.length - 1; i++) {
var currentLineSkip = baseLineskip;
var glyphMaxHeight = this.getGlyphMaxHeight(segmentedNodesFixed[i]);
if (currentLineSkip === null || glyphMaxHeight > currentLineSkip) {
currentLineSkip = glyphMaxHeight;
}
var currentLineBox = {
x: null,
y: null,
textStyle: exports.defaultTextStyle,
direction: frame.directionInsideLine,
width: frame.width,
height: currentLineSkip,
content: segmentedNodeUnglue[i],
};
bigBoxContent.push(currentLineBox);
}
bigBox.content = bigBoxContent;
return bigBox;
}
/**
* get the max height of the glyph`[a, b, c]`
* @param nodeLine the node line [a, b, c, ...]
* @returns
*/
getGlyphMaxHeight(nodeLine) {
let segmentedNodeLineHeight = nodeLine.map((x) => { if ("height" in x && x.height > 0.0) {
return x.height;
}
else {
return 0.0;
} });
let maxHeight = Math.max(...segmentedNodeLineHeight);
return maxHeight;
}
removeGlue(nodeLine, frame) {
let breakLineAlgorithms = new breakLines.BreakLineAlgorithm();
let glueRemoved = nodeLine.filter((x) => !breakLineAlgorithms.isHGlue(x));
let onlyGlue = nodeLine.filter((x) => breakLineAlgorithms.isHGlue(x));
let sumStretchFactor = onlyGlue.map((x) => { if ("stretchFactor" in x) {
return x.stretchFactor;
}
else {
return 0;
} })
.reduce((acc, cur) => acc + cur, 0);
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 - glueRemovedWidth;
var res = [];
for (var i = 0; i < nodeLine.length; i++) {
var ele = nodeLine[i];
if (breakLineAlgorithms.isHGlue(ele)) {
let tmp = {
x: null,
y: null,
textStyle: null,
direction: frame.directionInsideLine,
width: ele.stretchFactor / sumStretchFactor * offset,
height: 0,
content: "",
};
res.push(tmp);
}
else {
res.push(ele);
}
}
return res;
}
/**
* remove breakpoints
* @param boxitemline boxitem in a line with a breakpoint
* @returns boxitemline with break points removed
*/
removeBreakPoints(boxitemline) {
var res = [];
let breakLineAlgorithms = new breakLines.BreakLineAlgorithm();
for (var i = 0; i < boxitemline.length; i++) {
let ele = boxitemline[i];
if (breakLineAlgorithms.isBreakPoint(ele)) {
if (i == boxitemline.length - 1) {
res.push(ele.newLined);
}
else {
res.push(ele.original);
}
}
else {
res.push(ele);
}
}
return res;
}
}
exports.Clo = Clo;
/*

View file

@ -438,14 +438,133 @@ export class Clo{
let defaultFontStyle : TextStyle = this.attrs["defaultFrameStyle"].textStyle;
let a = await calculateTextWidthHeight(preprocessed, defaultFontStyle);
let breakLineAlgorithms = new breakLines.BreakLineAlgorithm();
// TODO
console.log(util.inspect(a, true, 100));
console.log(breakLines.totalCost(a,3,100));
//console.log(breakLineAlgorithms.totalCost(a,70));
let segmentedNodes = breakLineAlgorithms.segmentedNodes(a, 70);
console.log(this.segmentedNodesToFrameBox(segmentedNodes, <FrameBox>this.attrs["defaultFrameStyle"]));
}
segmentedNodesToFrameBox(segmentedNodes : BoxesItem[][], frame : FrameBox) : Box{
let baseLineskip = frame.baseLineskip;
let boxArrayEmpty : Box[] = [];
let bigBox : Box = {
x : frame.x,
y : frame.y,
textStyle : frame.textStyle,
direction : frame.direction,
width : frame.width,
height : frame.height,
content : boxArrayEmpty,
}
var bigBoxContent : Box[] = boxArrayEmpty;
let segmentedNodesFixed = segmentedNodes.map((x)=>this.removeBreakPoints
(x).flat());
let segmentedNodeUnglue = segmentedNodesFixed.map((x)=>this.removeGlue(x, frame).flat());
for (var i=0; i<segmentedNodesFixed.length-1; i++){
var currentLineSkip = baseLineskip;
var glyphMaxHeight = this.getGlyphMaxHeight(segmentedNodesFixed[i]);
if (currentLineSkip === null || glyphMaxHeight >currentLineSkip ){
currentLineSkip = glyphMaxHeight;
}
var currentLineBox : Box = {
x : null,
y : null,
textStyle : defaultTextStyle,
direction : frame.directionInsideLine,
width : frame.width,
height : currentLineSkip,
content : <Box[]>segmentedNodeUnglue[i],
}
bigBoxContent.push(currentLineBox);
}
bigBox.content = bigBoxContent;
return bigBox;
}
/**
* get the max height of the glyph`[a, b, c]`
* @param nodeLine the node line [a, b, c, ...]
* @returns
*/
getGlyphMaxHeight(nodeLine : BoxesItem[]) : number{
let segmentedNodeLineHeight = nodeLine.map((x : BoxesItem)=>{if ("height" in x && x.height > 0.0){return x.height}else{return 0.0}});
let maxHeight = Math.max(...segmentedNodeLineHeight);
return maxHeight;
}
removeGlue(nodeLine : BoxesItem[], frame : FrameBox) : BoxesItem[]{
let breakLineAlgorithms = new breakLines.BreakLineAlgorithm();
let glueRemoved = nodeLine.filter((x)=>!breakLineAlgorithms.isHGlue(x));
let onlyGlue = nodeLine.filter((x)=>breakLineAlgorithms.isHGlue(x));
let sumStretchFactor = onlyGlue.map((x)=>{if("stretchFactor" in x){ return x.stretchFactor} else{return 0;}})
.reduce((acc, cur)=>acc+cur , 0);
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 - glueRemovedWidth;
var res = [];
for (var i=0; i<nodeLine.length; i++){
var ele = nodeLine[i];
if (breakLineAlgorithms.isHGlue(ele)){
let tmp : Box = {
x : null,
y : null,
textStyle : null,
direction : frame.directionInsideLine,
width : ele.stretchFactor / sumStretchFactor * offset,
height : 0,
content : "",
}
res.push(tmp);
}else{
res.push(ele);
}
}
return res;
}
/**
* remove breakpoints
* @param boxitemline boxitem in a line with a breakpoint
* @returns boxitemline with break points removed
*/
removeBreakPoints(boxitemline : BoxesItem[]) : BoxesItem[]{
var res : BoxesItem[] = [];
let breakLineAlgorithms = new breakLines.BreakLineAlgorithm();
for (var i = 0; i<boxitemline.length; i++){
let ele = boxitemline[i];
if (breakLineAlgorithms.isBreakPoint(ele)){
if (i == boxitemline.length-1){
res.push(ele.newLined);
}else{
res.push(ele.original);
}
}else{
res.push(ele);
}
}
return res;
}
}
/*
export let a = new Clo();
export default a; */