diff --git a/sites/shared/components/workbench/exporting/export-handler.mjs b/sites/shared/components/workbench/exporting/export-handler.mjs index 4cc730a74eb..ca9417af2d0 100644 --- a/sites/shared/components/workbench/exporting/export-handler.mjs +++ b/sites/shared/components/workbench/exporting/export-handler.mjs @@ -155,13 +155,11 @@ export const handleExport = async ({ let pattern = themedPattern(Design, settings, { layout }, format, t) // a specified size should override the settings one - if (format !== 'pdf') { - pageSettings.size = format - } + pageSettings.size = format try { // add pages to pdf exports - if (format !== 'svg') { + if (!exportTypes.exportForEditing.includes(format)) { pattern.use( pagesPlugin({ ...pageSettings, @@ -184,11 +182,13 @@ export const handleExport = async ({ pattern.draft() workerArgs.svg = pattern.render() + if (format === 'pdf') pageSettings.size = [pattern.width, pattern.height] + // add the svg and pages data to the worker args workerArgs.pages = pattern.setStores[pattern.activeSet].get('pages') // add cutting layouts if requested - if (format !== 'svg' && pageSettings.cutlist) { + if (!exportTypes.exportForEditing.includes(format) && pageSettings.cutlist) { workerArgs.cutLayouts = generateCutLayouts(pattern, Design, settings, format, t, ui) } } catch (err) { diff --git a/sites/shared/components/workbench/exporting/export-worker.js b/sites/shared/components/workbench/exporting/export-worker.js index c2ac2040a27..ce0006041de 100644 --- a/sites/shared/components/workbench/exporting/export-worker.js +++ b/sites/shared/components/workbench/exporting/export-worker.js @@ -4,6 +4,7 @@ import yaml from 'js-yaml' import axios from 'axios' import { PdfMaker } from './pdf-maker' +import { SinglePdfMaker } from './single-pdf-maker.mjs' /** when the worker receives data from the page, do the appropriate export */ addEventListener('message', async (e) => { @@ -49,7 +50,7 @@ const exportYaml = (settings) => exportBlob(yaml.dump(settings), 'application/x- const exportSvg = (svg) => exportBlob(svg, 'image/svg+xml') const exportPdf = async (data) => { - const maker = new PdfMaker(data) + const maker = data.format === 'pdf' ? new SinglePdfMaker(data) : new PdfMaker(data) await maker.makePdf() postSuccess(await maker.toBlob()) } diff --git a/sites/shared/components/workbench/exporting/pdf-maker.mjs b/sites/shared/components/workbench/exporting/pdf-maker.mjs index 8598821d72c..4838da6768e 100644 --- a/sites/shared/components/workbench/exporting/pdf-maker.mjs +++ b/sites/shared/components/workbench/exporting/pdf-maker.mjs @@ -1,4 +1,4 @@ -import PDFDocument from 'pdfkit/js/pdfkit.standalone' +import { Pdf, mmToPoints } from './pdf.mjs' import SVGtoPDF from 'svg-to-pdfkit' import { logoPath } from 'shared/components/logos/freesewing.mjs' @@ -8,11 +8,6 @@ const logoSvg = ` ` -/** - * PdfKit, the library we're using for pdf generation, uses points as a unit, so when we tell it things like where to put the svg and how big the svg is, we need those numbers to be in points - * The svg uses mm internally, so when we do spatial reasoning inside the svg, we need to know values in mm - * */ -const mmToPoints = 2.834645669291339 const lineStart = 50 /** * Freesewing's first explicit class? @@ -58,7 +53,10 @@ export class PdfMaker { this.strings = strings this.cutLayouts = cutLayouts - this.initPdf() + this.pdf = Pdf({ + size: this.pageSettings.size.toUpperCase(), + layout: this.pageSettings.orientation, + }) this.margin = this.pageSettings.margin * mmToPoints // margin is in mm because it comes from us, so we convert it to points this.pageHeight = this.pdf.page.height - this.margin * 2 // this is in points because it comes from pdfKit @@ -73,22 +71,6 @@ export class PdfMaker { this.svgHeight = this.rows * this.pageHeight } - /** create the pdf document */ - initPdf() { - // instantiate with the correct size and orientation - this.pdf = new PDFDocument({ - size: this.pageSettings.size.toUpperCase(), - layout: this.pageSettings.orientation, - }) - - // PdfKit wants to flush the buffer on each new page. - // We can't save directly from inside a worker, so we have to manage the buffers ourselves so we can return a blob - this.buffers = [] - - // use a listener to add new data to our buffer storage - this.pdf.on('data', this.buffers.push.bind(this.buffers)) - } - /** make the pdf */ async makePdf() { await this.generateCoverPage() @@ -97,21 +79,8 @@ export class PdfMaker { } /** convert the pdf to a blob */ - toBlob() { - return new Promise((resolve) => { - // have to do it this way so that the document flushes everything to buffers - this.pdf.on('end', () => { - // convert buffers to a blob - resolve( - new Blob(this.buffers, { - type: 'application/pdf', - }) - ) - }) - - // end the stream - this.pdf.end() - }) + async toBlob() { + return this.pdf.toBlob() } /** generate the cover page for the pdf */ diff --git a/sites/shared/components/workbench/exporting/pdf.mjs b/sites/shared/components/workbench/exporting/pdf.mjs new file mode 100644 index 00000000000..392c10b3900 --- /dev/null +++ b/sites/shared/components/workbench/exporting/pdf.mjs @@ -0,0 +1,45 @@ +import PDFDocument from 'pdfkit/js/pdfkit.standalone' + +/** + * PdfKit, the library we're using for pdf generation, uses points as a unit, so when we tell it things like where to put the svg and how big the svg is, we need those numbers to be in points + * The svg uses mm internally, so when we do spatial reasoning inside the svg, we need to know values in mm + * */ +export const mmToPoints = 2.834645669291339 + +/** + * A PDFKit Pdf with a few of our utilities included + * @returns + */ +export const Pdf = ({ size, layout }) => { + const pdf = new PDFDocument({ + size, + layout, + }) + + // PdfKit wants to flush the buffer on each new page. + // We can't save directly from inside a worker, so we have to manage the buffers ourselves so we can return a blob + const buffers = [] + + // use a listener to add new data to our buffer storage + pdf.on('data', buffers.push.bind(buffers)) + + /** convert the pdf to a blob */ + pdf.toBlob = function () { + return new Promise((resolve) => { + // have to do it this way so that the document flushes everything to buffers + pdf.on('end', () => { + // convert buffers to a blob + resolve( + new Blob(buffers, { + type: 'application/pdf', + }) + ) + }) + + // end the stream + pdf.end() + }) + } + + return pdf +} diff --git a/sites/shared/components/workbench/exporting/single-pdf-maker.mjs b/sites/shared/components/workbench/exporting/single-pdf-maker.mjs new file mode 100644 index 00000000000..f05fc58966c --- /dev/null +++ b/sites/shared/components/workbench/exporting/single-pdf-maker.mjs @@ -0,0 +1,23 @@ +import { Pdf, mmToPoints } from './pdf.mjs' +import SVGtoPDF from 'svg-to-pdfkit' + +/** + * Basic exporter for a single-page pdf containing the rendered pattern. + * This generates a PDF that is the size of the pattern and has no additional frills*/ +export class SinglePdfMaker { + pdf + svg + + constructor({ svg, pageSettings }) { + this.pdf = Pdf({ size: pageSettings.size.map((s) => s * mmToPoints) }) + this.svg = svg + } + + async makePdf() { + await SVGtoPDF(this.pdf, this.svg) + } + + async toBlob() { + return this.pdf.toBlob() + } +} diff --git a/sites/shared/components/workbench/views/print/index.mjs b/sites/shared/components/workbench/views/print/index.mjs index a5c3719eb23..5c901e38e43 100644 --- a/sites/shared/components/workbench/views/print/index.mjs +++ b/sites/shared/components/workbench/views/print/index.mjs @@ -73,7 +73,7 @@ export const PrintView = ({ const exportIt = () => { handleExport({ - format: 'pdf', + format: pageSettings.size, settings, design, t,