X-Git-Url: https://git.kianting.info/?a=blobdiff_plain;f=src%2Flibclo%2Findex.ts;h=bcd6a46704d96b05580f4f81eea3e86eef1b214e;hb=134485a6d637ce5b422098c08bccb274c73bca86;hp=917cf68afbb1f8061105241b729ee808e85ea543;hpb=c3dc58d74afa6b298d84bad90d63c027a32a954a;p=clo diff --git a/src/libclo/index.ts b/src/libclo/index.ts index 917cf68..bcd6a46 100644 --- a/src/libclo/index.ts +++ b/src/libclo/index.ts @@ -1,7 +1,14 @@ -import { isKeyObject, isStringObject } from "util/types"; +import { isBoxedPrimitive, isKeyObject, isStringObject } from "util/types"; import {tkTree} from "../parser"; -import {FontStyle, TextStyle, TextWeight} from "../canva"; +import {FontStyle, TextStyle, TextWeight, fontStyleTofont} from "../canva"; import { JSDOM } from "jsdom"; +import * as fontkit from "fontkit"; +import * as util from "node:util"; +import * as breakLines from "./breakLines"; +import "pdfkit"; +import PDFKitPage from "pdfkit/js/page"; +import { ColorTypes, PDFDocument, rgb } from "pdf-lib"; +import * as fs from "fs"; /** * TYPES @@ -20,6 +27,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 @@ -30,13 +52,21 @@ export interface FrameBox extends Box{ baseLineskip : number | null, } +export interface CharBox extends Box{ + minX: number, + maxX: number, + minY: number, + maxY: number, + +} + /** * a basic Box * - x : * - y : * - textStyle : * - direction : - * - width : + * - width : x_advance * - content : */ export interface Box{ @@ -188,7 +218,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); @@ -257,45 +288,92 @@ export function hyphenTkTree(arr : tkTree, lang: string) : tkTree{ * @param preprocessed * @param defaultFontStyle */ -export function calculateTextWidthHeight(preprocessed : tkTree, style : TextStyle): void { - var dom = new JSDOM(` - `); +export async function calculateTextWidthHeight(element : tkTree, style : TextStyle): Promise { + var res = []; - try { - let canvas = dom.window.document.getElementById("canvas"); - console.log(canvas); - - /*if (!(canvas instanceof HTMLElement)){ - throw new Error('the in the jsdom\'s DOM is not found.'); - - }*/ - - let context = (canvas).getContext("2d"); - console.log(context); - if (context == null){ - throw new Error('`canvas.getContext("2d");` can\'t be executed.'); - - } + for (var i=0; i { + var result : BoxesItem = []; + + let fontPair = fontStyleTofont(style); + if (fontPair.path.match(/\.ttc$/)){ + var font = await fontkit.openSync(fontPair.path, fontPair.psName); + } + else{ + var font = await fontkit.openSync(fontPair.path); + } + if (!Array.isArray(element)){ + var run = font.layout(element, undefined, undefined, undefined, "ltr"); + + + + for (var j=0;jthis.attrs["defaultFrameStyle"])); + + // generate pdf + const pdfDoc = await PDFDocument.create(); + var page = pdfDoc.addPage(); + page.drawText('You can create PDFs!'); + + for (var j = 0; j<1000; j+=5){ + if (j %50 == 0){ + page.drawText(i.toString(), {x: 50, y: j}); + } + + page.drawLine({ + start: { x: 0, y: j }, + end: { x: 1000, y: j }, + thickness: 0.5, + color: rgb(0.75, 0.2, 0.2), + opacity: 0.20, + }); + } + + for (var i = 0; i<1000; i+=5){ + if (i % 50 == 0){ + page.drawText(i.toString(), {x: i, y: 50}); + } + page.drawLine({ + start: { x: i, y: 0 }, + end: { x: i, y: 1000 }, + thickness: 0.5, + color: rgb(0.75, 0.2, 0.2), + opacity: 0.20, + }); + } + pdfDoc.save(); + + const pdfBytes = await pdfDoc.save(); + fs.writeFileSync("blank.pdf", pdfBytes); + } + + 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; 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 - glueRemovedWidth; + var res = []; + for (var i=0; i