X-Git-Url: https://git.kianting.info/?a=blobdiff_plain;f=src%2Flibclo%2Findex.js;h=17b36b41752e06493d9c785c3002b787ab2be69d;hb=134485a6d637ce5b422098c08bccb274c73bca86;hp=5cfaabe918cb0fb18ac1d7e2485a06180526956c;hpb=830387283a88441140be5a9ebd13f36551bd15c7;p=clo diff --git a/src/libclo/index.js b/src/libclo/index.js index 5cfaabe..17b36b4 100644 --- a/src/libclo/index.js +++ b/src/libclo/index.js @@ -35,6 +35,10 @@ 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 breakLines = __importStar(require("./breakLines")); +require("pdfkit"); +const pdf_lib_1 = require("pdf-lib"); +const fs = __importStar(require("fs")); /** * TYPES */ @@ -177,7 +181,8 @@ function spacesToBreakpoint(arr, clo) { 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); @@ -244,7 +249,7 @@ function calculateTextWidthHeight(element, style) { for (var i = 0; i < element.length; i++) { res.push(yield calculateTextWidthHeightAux(element[i], style)); } - console.log(res); + res = res.flat(); return res; }); } @@ -286,12 +291,26 @@ function calculateTextWidthHeightAux(element, style) { return result; } else if (element[0] == "bp") { - let beforeNewLine = yield calculateTextWidthHeightAux(element[1], style); + var beforeNewLine = yield calculateTextWidthHeightAux(element[1], style); + if (Array.isArray(beforeNewLine)) { + beforeNewLine = beforeNewLine.flat(); + } let afterNewLine = yield calculateTextWidthHeightAux(element[2], style); - return ["bp", beforeNewLine, afterNewLine]; + 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[1], style); + return calculateTextWidthHeight(element, style); } }); } @@ -334,16 +353,166 @@ class Clo { 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; } - // generate the width and height of the stream - let defaultFontStyle = this.attrs["defaultFrameStyle"].textStyle; - calculateTextWidthHeight(preprocessed, defaultFontStyle); - // TODO - console.log(preprocessed); + 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;