"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
Object.defineProperty(exports, "__esModule", { value: true });
-exports.Clo = 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;
+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 jsdom_1 = require("jsdom");
+const fontkit = __importStar(require("fontkit"));
+const breakLines = __importStar(require("./breakLines"));
+require("pdfkit");
+const pdf_lib_1 = require("pdf-lib");
+const fs = __importStar(require("fs"));
/**
* TYPES
*/
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);
* @param preprocessed
* @param defaultFontStyle
*/
-function calculateTextWidthHeight(preprocessed, style) {
- var dom = new jsdom_1.JSDOM(`<!DOCTYPE html><html><head></head>
- <body><canvas id="canvas"></canvas></body></html>`);
- try {
- let canvas = dom.window.document.getElementById("canvas");
- console.log(canvas);
- /*if (!(canvas instanceof HTMLElement)){
- throw new Error('the <canvas="canvas"> 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.');
+function calculateTextWidthHeight(element, style) {
+ return __awaiter(this, void 0, void 0, function* () {
+ var res = [];
+ for (var i = 0; i < element.length; i++) {
+ res.push(yield calculateTextWidthHeightAux(element[i], style));
}
- context.font = `normal normal 10pt ${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);
- }
- catch (error) {
- console.log("Exception " + error);
- }
+ res = res.flat();
+ return res;
+ });
}
exports.calculateTextWidthHeight = calculateTextWidthHeight;
+/**
+ * calculate the text width and Height with a given `TextStyle`
+ * @param preprocessed
+ * @param defaultFontStyle
+ */
+function calculateTextWidthHeightAux(element, style) {
+ return __awaiter(this, void 0, void 0, function* () {
+ var result = [];
+ let fontPair = (0, canva_1.fontStyleTofont)(style);
+ if (fontPair.path.match(/\.ttc$/)) {
+ var font = yield fontkit.openSync(fontPair.path, fontPair.psName);
+ }
+ else {
+ var font = yield fontkit.openSync(fontPair.path);
+ }
+ if (!Array.isArray(element)) {
+ var run = font.layout(element, undefined, undefined, undefined, "ltr");
+ for (var j = 0; j < run.glyphs.length; j++) {
+ let runGlyphsItem = run.glyphs[j];
+ let item = {
+ x: null,
+ y: null,
+ textStyle: style,
+ direction: Direction.LTR,
+ width: (runGlyphsItem.advanceWidth) * (style.size) / 1000,
+ height: (runGlyphsItem.bbox.maxY - runGlyphsItem.bbox.minY) * (style.size) / 1000,
+ content: element[j],
+ minX: runGlyphsItem.bbox.minX,
+ maxX: runGlyphsItem.bbox.maxX,
+ minY: runGlyphsItem.bbox.minY,
+ maxY: runGlyphsItem.bbox.maxY
+ };
+ result.push(item);
+ }
+ return result;
+ }
+ else if (element[0] == "bp") {
+ var beforeNewLine = yield calculateTextWidthHeightAux(element[1], style);
+ if (Array.isArray(beforeNewLine)) {
+ beforeNewLine = beforeNewLine.flat();
+ }
+ let afterNewLine = yield calculateTextWidthHeightAux(element[2], style);
+ if (Array.isArray(afterNewLine)) {
+ afterNewLine = afterNewLine.flat();
+ }
+ let breakPointNode = {
+ original: beforeNewLine,
+ newLined: afterNewLine,
+ };
+ return breakPointNode;
+ }
+ else if (element[0] == "hglue" && !Array.isArray(element[1])) {
+ let hGlue = { stretchFactor: parseFloat(element[1]) };
+ return hGlue;
+ }
+ else {
+ return calculateTextWidthHeight(element, style);
+ }
+ });
+}
+exports.calculateTextWidthHeightAux = calculateTextWidthHeightAux;
/**
* whole document-representing class
*/
this.preprocessors.push(f);
}
generatePdf() {
- // preprocessed
- var preprocessed = this.mainStream;
- for (var i = 0; i < this.preprocessors.length; i++) {
- preprocessed = this.preprocessors[i](preprocessed, this);
+ return __awaiter(this, void 0, void 0, function* () {
+ // preprocessed
+ var preprocessed = this.mainStream;
+ for (var i = 0; i < this.preprocessors.length; i++) {
+ preprocessed = this.preprocessors[i](preprocessed, this);
+ }
+ // 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(breakLineAlgorithms.totalCost(a,70));
+ let segmentedNodes = breakLineAlgorithms.segmentedNodes(a, 70);
+ console.log(this.segmentedNodesToFrameBox(segmentedNodes, this.attrs["defaultFrameStyle"]));
+ // generate pdf
+ const pdfDoc = yield pdf_lib_1.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: (0, pdf_lib_1.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: (0, pdf_lib_1.rgb)(0.75, 0.2, 0.2),
+ opacity: 0.20,
+ });
+ }
+ pdfDoc.save();
+ const pdfBytes = yield pdfDoc.save();
+ fs.writeFileSync("blank.pdf", pdfBytes);
+ });
+ }
+ 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);
+ }
}
- // generate the width and height of the stream
- let defaultFontStyle = this.attrs["defaultFrameStyle"].textStyle;
- calculateTextWidthHeight(preprocessed, defaultFontStyle);
- // TODO
- console.log(preprocessed);
+ return res;
}
}
exports.Clo = Clo;