export function toPDF()

in packages/maker.js/src/core/pdf.ts [11:113]


    export function toPDF(doc: PDFKit.PDFDocument, modelToExport: IModel, options?: IPDFRenderOptions) {
        if (!modelToExport) return;

        //fixup options
        var opts: IPDFRenderOptions = {
            fontName: 'Courier',
            fontSize: 9,
            origin: [0, 0],
            stroke: "#000",
        };

        extendObject(opts, options);

        //try to get the unit system from the itemToExport
        var scale = 1;
        var exportUnits = opts.units || modelToExport.units;
        if (exportUnits) {
            //convert to inch
            scale = units.conversionScale(exportUnits, unitType.Inch);
        } else {
            //assume pixels, convert to inch
            scale = 1 / 100;
        }

        //from inch to PDF PPI
        scale *= 72;

        //TODO scale each element without a whole clone
        var scaledModel = model.scale(cloneObject(modelToExport), scale);

        var size = measure.modelExtents(scaledModel);

        var left = -size.low[0];
        var offset: IPoint = [left, size.high[1]];

        offset = point.add(offset, opts.origin);

        model.findChains(
            scaledModel,
            function (chains: IChain[], loose: IWalkPath[], layer: string) {

                function single(walkedPath: IWalkPath) {
                    var pathData = pathToSVGPathData(walkedPath.pathContext, walkedPath.offset, offset);
                    doc.path(pathData).stroke(opts.stroke);
                }

                chains.map(function (chain: IChain) {
                    if (chain.links.length > 1) {
                        var pathData = chainToSVGPathData(chain, offset);
                        doc.path(pathData).stroke(opts.stroke);

                    } else {
                        var walkedPath = chain.links[0].walkedPath;
                        if (walkedPath.pathContext.type === pathType.Circle) {

                            var fixedPath: IPath;
                            path.moveTemporary([walkedPath.pathContext], [walkedPath.offset], function () {
                                fixedPath = path.mirror(walkedPath.pathContext, false, true);
                            });
                            path.moveRelative(fixedPath, offset);

                            //TODO use only chainToSVGPathData instead of circle, so that we can use fill

                            doc.circle(fixedPath.origin[0], fixedPath.origin[1], (<IPathCircle>walkedPath.pathContext).radius).stroke(opts.stroke);

                        } else {
                            single(walkedPath);
                        }
                    }
                });

                loose.map(single);

            },
            { byLayers: false }
        );

        doc.font(opts.fontName).fontSize(opts.fontSize);

        model.getAllCaptionsOffset(scaledModel).forEach(caption => {

            //measure the angle of the line, prior to mirroring
            const a = angle.ofLineInDegrees(caption.anchor);

            //mirror into pdf y coords
            const anchor = path.mirror(caption.anchor, false, true) as IPathLine;

            //move mirrored line by document offset
            path.moveRelative(anchor, offset);

            //measure center point of text
            const text = caption.text;
            const textCenter: IPoint = [doc.widthOfString(text) / 2, doc.heightOfString(text) / 2];

            //get center point on line
            const center = point.middle(anchor) as number[];
            const textOffset = point.subtract(center, textCenter);

            doc.rotate(-a, { origin: center });
            doc.text(text, textOffset[0], textOffset[1]);
            doc.rotate(a, { origin: center });
        });
    }