X-Git-Url: https://git.kianting.info/?a=blobdiff_plain;f=src%2Flibclo%2Findex.ts;h=fa8c6609296c33270f157299e48ac21f097a2f68;hb=e9819c8bc28d209d79461117d5b70f7b6b94abb6;hp=bb884fae1260a5fed6209a6895b835091f3a4607;hpb=830387283a88441140be5a9ebd13f36551bd15c7;p=clo diff --git a/src/libclo/index.ts b/src/libclo/index.ts index bb884fa..fa8c660 100644 --- a/src/libclo/index.ts +++ b/src/libclo/index.ts @@ -1,8 +1,10 @@ -import { isBoxedPrimitive, isKeyObject, isStringObject } from "util/types"; import {tkTree} from "../parser"; import {FontStyle, TextStyle, TextWeight, fontStyleTofont} from "../canva"; -import { JSDOM } from "jsdom"; import * as fontkit from "fontkit"; +import * as breakLines from "./breakLines"; +const PDFDocument = require('pdfkit'); +import * as fs from "fs"; + /** * TYPES @@ -21,6 +23,21 @@ export enum Direction{ BTT, } +/** + * Horizonal glue. + * - stretchFactor : the stretch factor in float + */ +export interface HGlue{ + stretchFactor: number +} + +export interface BreakPoint{ + original : BoxesItem, + newLined : BoxesItem +} + +export type BoxesItem = HGlue | Box | BreakPoint | BoxesItem[] ; + /** * frame box is a subclass of box * - directionInsideLine : text direction inside a line @@ -77,10 +94,10 @@ export const defaultFrameStyle : FrameBox = { direction : Direction.TTB, baseLineskip : ptToPx(15), textStyle : defaultTextStyle, - 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, + x : A4_IN_PX.width * 0.10 * 0.75, + y : A4_IN_PX.height * 0.10 * 0.75, + width : A4_IN_PX.width * 0.80 , + height : A4_IN_PX.height * 0.80 , content : null, }; @@ -197,7 +214,8 @@ export function spacesToBreakpoint(arr : tkTree, clo : Clo) : tkTree{ for (let i = 0; i < arr.length; i++){ var item = arr[i]; if (!Array.isArray(item) && item.match(spacePattern)){ - result.push([ 'bp', item, "" ]); // push a newline command to the result `tkTree` + // push a breakpoint command to the result `tkTree` + result.push([ 'bp', [["hglue", "0.1"], item] , "" ]); } else{ result.push(item); @@ -266,14 +284,14 @@ export function hyphenTkTree(arr : tkTree, lang: string) : tkTree{ * @param preprocessed * @param defaultFontStyle */ -export async function calculateTextWidthHeight(element : tkTree, style : TextStyle): Promise { +export async function calculateTextWidthHeight(element : tkTree, style : TextStyle): Promise { var res = []; for (var i=0; i { - var result : any = []; +export async function calculateTextWidthHeightAux(element : tkTree, style : TextStyle): Promise { + var result : BoxesItem = []; @@ -310,8 +328,8 @@ export async function calculateTextWidthHeightAux(element : tkTree, style : Text y : null, textStyle : style, direction : Direction.LTR, - width : (runGlyphsItem.advanceWidth)*(style.size)/1000, - height : (runGlyphsItem.bbox.maxY - runGlyphsItem.bbox.minY)*(style.size)/1000, + width : (runGlyphsItem.advanceWidth)*(style.size)*0.75/1000, + height : (runGlyphsItem.bbox.maxY - runGlyphsItem.bbox.minY)*(style.size)*0.75/1000, content : element[j], minX : runGlyphsItem.bbox.minX, maxX : runGlyphsItem.bbox.maxX, @@ -328,12 +346,29 @@ export async function calculateTextWidthHeightAux(element : tkTree, style : Text }else if(element[0] == "bp"){ - let beforeNewLine = await calculateTextWidthHeightAux(element[1], style); + + var beforeNewLine = await calculateTextWidthHeightAux(element[1], style); + if (Array.isArray(beforeNewLine)){ + beforeNewLine = beforeNewLine.flat(); + } + let afterNewLine = await calculateTextWidthHeightAux(element[2], style); + if (Array.isArray(afterNewLine)){ + afterNewLine = afterNewLine.flat(); + } + + let breakPointNode : BreakPoint = { + original : beforeNewLine, + newLined : afterNewLine, + } - return ["bp", beforeNewLine, afterNewLine]; - }else{ - return calculateTextWidthHeight(element[1], style); + return breakPointNode; + }else if(element[0] == "hglue" && !Array.isArray(element[1])){ + let hGlue : HGlue = {stretchFactor : parseFloat(element[1])} + return hGlue; + } + else{ + return calculateTextWidthHeight(element, style); } } @@ -392,7 +427,7 @@ export class Clo{ this.preprocessors.push(f); } - public generatePdf(){ + public async generatePdf(){ // preprocessed var preprocessed = this.mainStream; for (var i = 0; ithis.attrs.defaultFrameStyle); + + + + let boxesFixed = this.fixenBoxesPosition(segmentedNodesToBox); + + + + + // generate pdf7 + const doc = new PDFDocument({size: 'A4'}); + doc.pipe(fs.createWriteStream('output.pdf')); + this.grid(doc); + + await this.putText(doc, boxesFixed); + // putChar + doc.end(); + + } + + async putText(doc : PDFKit.PDFDocument, box : Box): Promise{ + + if (box.textStyle !== null){ + let fontInfo = fontStyleTofont(box.textStyle); + + if (fontInfo.path.match(/\.ttc$/g)){ + doc + .font(fontInfo.path, fontInfo.psName) + .fontSize(box.textStyle.size*0.75);} + else{ + doc + .font(fontInfo.path) + .fontSize(box.textStyle.size*0.75); + } + + if (box.textStyle.color !== undefined){ + doc.fill(box.textStyle.color); + } + + if (Array.isArray(box.content)){ + for (var k=0; kthis.removeBreakPoints +(x).flat()); + let segmentedNodeUnglue = segmentedNodesFixed.map((x)=>this.removeGlue(x, frame).flat()); + + for (var i=0; icurrentLineSkip ){ + currentLineSkip = glyphMaxHeight; + } + + var currentLineBox : Box = { + x : null, + y : null, + textStyle : 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 : 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 * 0.75 - glueRemovedWidth; + console.log("OFFSET", offset); + var res = []; + for (var i=0; i