X-Git-Url: https://git.kianting.info/?a=blobdiff_plain;f=src%2Flibclo%2Findex.ts;h=e5c2108442e2deae04678c9a11e261f70f6f5ed7;hb=2b1a59e963a3610c8f664af3dd6b03afb8d89646;hp=917cf68afbb1f8061105241b729ee808e85ea543;hpb=c3dc58d74afa6b298d84bad90d63c027a32a954a;p=clo
diff --git a/src/libclo/index.ts b/src/libclo/index.ts
index 917cf68..e5c2108 100644
--- a/src/libclo/index.ts
+++ b/src/libclo/index.ts
@@ -1,7 +1,10 @@
-import { isKeyObject, isStringObject } from "util/types";
import {tkTree} from "../parser";
-import {FontStyle, TextStyle, TextWeight} from "../canva";
-import { JSDOM } from "jsdom";
+import {FontStyle, TextStyle, TextWeight, fontStyleTofont} from "../canva";
+import * as fontkit from "fontkit";
+import * as breakLines from "./breakLines";
+const PDFDocument = require('pdfkit');
+import * as fs from "fs";
+
/**
* TYPES
@@ -20,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
@@ -30,13 +48,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 :
+ * - x : pt
+ * - y : pt
* - textStyle :
* - direction :
- * - width :
+ * - width : x_advance pt
* - content :
*/
export interface Box{
@@ -68,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 ,
+ y : A4_IN_PX.height * 0.10 ,
+ width : A4_IN_PX.width * 0.80 ,
+ height : A4_IN_PX.height * 0.80 ,
content : null,
};
@@ -188,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);
@@ -257,45 +284,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);
+ for (var i=0; i in the jsdom\'s DOM is not found.');
-
- }*/
+ res = res.flat();
- let context = (canvas).getContext("2d");
- console.log(context);
- if (context == null){
- throw new Error('`canvas.getContext("2d");` can\'t be executed.');
-
- }
+ return res;
+}
- context.font = `normal normal ${style.size}px ${style.family}`;
- console.log(context.font);
- let txt = `Hello john`;
- console.log(txt);
- let measured = context.measureText(txt);
- let width = measured.width;
- let height = measured.actualBoundingBoxAscent;
- let depth = measured.actualBoundingBoxDescent;
- console.log("width: "+width);
- console.log("height: "+height);
- console.log("depth: "+depth);
+/**
+ * calculate the text width and Height with a given `TextStyle`
+ * @param preprocessed
+ * @param defaultFontStyle
+ */
+export async function calculateTextWidthHeightAux(element : tkTree, style : TextStyle): Promise {
+ var result : BoxesItem = [];
+
- } catch (error) {
- console.log("Exception "+error);
+ 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);
+
+
+
+ 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); // 0.75 must added!
+ }
+
+ 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;
+ var res = [];
+ for (var i=0; i