2022-08-16 00:33:35 -05:00
|
|
|
import {sizes} from '../layout/print/plugin'
|
|
|
|
import PDFDocument from 'pdfkit/js/pdfkit.standalone'
|
|
|
|
import SVGtoPDF from 'svg-to-pdfkit'
|
|
|
|
import fileSaver from 'file-saver'
|
|
|
|
|
|
|
|
const pointsPerPx = (72/96);
|
|
|
|
const pxPerMm = 3.77953
|
|
|
|
const pointsPerMm = pxPerMm * pointsPerPx
|
|
|
|
|
|
|
|
export default class Exporter {
|
|
|
|
designName
|
|
|
|
svg
|
|
|
|
settings
|
2022-08-17 00:34:25 -05:00
|
|
|
pattern
|
2022-08-16 00:33:35 -05:00
|
|
|
|
|
|
|
pdf
|
|
|
|
pageWidth
|
|
|
|
pageHeight
|
|
|
|
margin
|
|
|
|
wPages
|
|
|
|
hPages
|
|
|
|
svgWidth
|
|
|
|
svgHeight
|
2022-08-17 00:34:25 -05:00
|
|
|
pagesWithContent = {}
|
2022-08-16 00:33:35 -05:00
|
|
|
|
|
|
|
|
|
|
|
constructor(designName, pattern, svg, settings) {
|
|
|
|
this.designName = designName || 'freesewing'
|
|
|
|
this.settings = settings
|
2022-08-17 00:34:25 -05:00
|
|
|
this.pattern = pattern
|
2022-08-16 00:33:35 -05:00
|
|
|
this.createPdf()
|
|
|
|
|
|
|
|
this.pageHeight = this.pdf.page.height
|
|
|
|
this.pageWidth = this.pdf.page.width
|
|
|
|
this.margin = this.settings.margin * pointsPerMm
|
|
|
|
|
|
|
|
let marginInMm = this.settings.margin
|
2022-08-17 00:34:25 -05:00
|
|
|
// let pageWidthInPx = this.pageWidth / pointsPerMm - marginInMm
|
|
|
|
// let pageHeightInPx = this.pageHeight / pointsPerMm - marginInMm
|
2022-08-16 00:33:35 -05:00
|
|
|
|
|
|
|
const divElem = document.createElement('div');
|
|
|
|
divElem.innerHTML = svg;
|
|
|
|
this.svg = divElem.firstElementChild;
|
|
|
|
|
2022-08-17 00:34:25 -05:00
|
|
|
const viewBox = this.svg.viewBox.baseVal
|
|
|
|
this.svgWidth = viewBox.width + viewBox.x
|
|
|
|
this.svgHeight = viewBox.height + viewBox.y
|
2022-08-16 00:33:35 -05:00
|
|
|
|
2022-08-17 00:34:25 -05:00
|
|
|
this.wPages = Math.ceil(this.svgWidth/this.pageWidthInPx)
|
|
|
|
this.hPages = Math.ceil(this.svgHeight/this.pageHeightInPx)
|
2022-08-16 00:33:35 -05:00
|
|
|
|
|
|
|
this.svgWidth = this.wPages * (this.pageWidth - this.margin)
|
|
|
|
this.svgHeight = this.hPages * (this.pageHeight - this.margin)
|
|
|
|
|
|
|
|
this.svg.setAttribute('height', this.svgWidth + 'pt')
|
|
|
|
this.svg.setAttribute('width', this.svgHeight + 'pt')
|
2022-08-17 00:34:25 -05:00
|
|
|
this.svg.setAttribute('viewBox', `0 0 ${this.wPages * this.pageWidthInPx} ${this.hPages * this.pageHeightInPx}`)
|
2022-08-16 00:33:35 -05:00
|
|
|
}
|
|
|
|
|
2022-08-17 00:34:25 -05:00
|
|
|
get pageWidthInPx() { return this.pageWidth / pointsPerMm - this.settings.margin}
|
|
|
|
get pageHeightInPx() { return this.pageHeight / pointsPerMm - this.settings.margin}
|
|
|
|
|
|
|
|
|
2022-08-16 00:33:35 -05:00
|
|
|
createPdf() {
|
|
|
|
this.pdf = new PDFDocument({
|
2022-08-17 00:34:25 -05:00
|
|
|
size: this.settings.size.toUpperCase(),
|
2022-08-16 00:33:35 -05:00
|
|
|
layout: this.settings.orientation
|
|
|
|
})
|
|
|
|
|
|
|
|
const buffers = [];
|
|
|
|
this.pdf.on('data', buffers.push.bind(buffers));
|
|
|
|
this.pdf.on('end', () => {
|
|
|
|
const blob = new Blob(buffers, {
|
|
|
|
type: 'application/pdf'
|
|
|
|
})
|
|
|
|
fileSaver.saveAs(blob, `freesewing-${this.designName}.pdf`)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-08-17 00:34:25 -05:00
|
|
|
scanPages() {
|
|
|
|
const layout = typeof this.pattern.settings.layout === 'object' ? this.pattern.settings.layout : this.pattern.autoLayout;
|
|
|
|
// const usableWidth = this.pageWidth - this.margin
|
|
|
|
// const usableHeight = this.pageHeight - this.margin
|
|
|
|
|
|
|
|
for (var h = 0; h < this.hPages; h++) {
|
|
|
|
this.pagesWithContent[h] = {}
|
|
|
|
for (var w = 0; w < this.wPages; w++) {
|
|
|
|
let x = w * this.pageWidthInPx
|
|
|
|
let y = h * this.pageHeightInPx
|
|
|
|
|
|
|
|
let hasContent = false
|
|
|
|
for (var p in layout.parts) {
|
|
|
|
let part = this.pattern.parts[p]
|
|
|
|
if (p === 'pages' || part.render === false) continue
|
|
|
|
|
|
|
|
let partLayout = layout.parts[p]
|
|
|
|
let partX = partLayout.move.x + part.topLeft.x
|
|
|
|
let partY = partLayout.move.y + part.topLeft.y
|
|
|
|
|
|
|
|
if (
|
|
|
|
partX < x + this.pageWidthInPx &&
|
|
|
|
partX + part.width > x &&
|
|
|
|
partY < y + this.pageHeightInPx &&
|
|
|
|
partY + part.height > y
|
|
|
|
) {
|
|
|
|
hasContent = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.pagesWithContent[h][w] = hasContent
|
|
|
|
if (!hasContent) {
|
|
|
|
let pageName = `_pages__row${h}-col${w}`
|
|
|
|
this.removeElem(pageName, 'circle', 'text')
|
|
|
|
this.removeElem(pageName + '-row-marker', 'text')
|
|
|
|
this.removeElem(pageName + '-col-marker', 'text')
|
|
|
|
this.removeElem(pageName + '-x-ruler', 'text')
|
|
|
|
this.removeElem(pageName + '-y-ruler', 'text')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
removeElem(pathId, ...suffixes) {
|
|
|
|
const that = this;
|
|
|
|
const elem = that.svg.getElementById(pathId)
|
|
|
|
if (elem) elem.setAttribute('class', 'hidden')
|
|
|
|
suffixes.forEach((s) => that.removeElem(`${pathId}-${s}`))
|
|
|
|
}
|
|
|
|
|
2022-08-16 00:33:35 -05:00
|
|
|
async export() {
|
2022-08-17 00:34:25 -05:00
|
|
|
this.scanPages()
|
2022-08-16 00:33:35 -05:00
|
|
|
await this.generateCoverPage()
|
|
|
|
await this.generatePages();
|
|
|
|
this.save()
|
|
|
|
}
|
|
|
|
|
|
|
|
async generateCoverPage() {
|
|
|
|
if (!this.settings.coverPage) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
let coverMargin = 100
|
|
|
|
|
|
|
|
let coverHeight = this.pageHeight - coverMargin * 2
|
|
|
|
let coverWidth = this.pageWidth - coverMargin * 2
|
|
|
|
|
|
|
|
await SVGtoPDF(this.pdf, this.svg.outerHTML, coverMargin, coverMargin, {
|
|
|
|
width: coverWidth,
|
|
|
|
height: coverHeight,
|
|
|
|
assumePt: true,
|
|
|
|
preserveAspectRatio: 'xMidYMid meet'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async generatePages() {
|
|
|
|
const options = {
|
|
|
|
assumePt: true,
|
|
|
|
width: this.svgWidth,
|
|
|
|
height: this.svgHeight,
|
|
|
|
preserveAspectRatio: 'xMinYMin slice'
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var h = 0; h < this.hPages; h++) {
|
|
|
|
for (var w = 0; w < this.wPages; w++) {
|
2022-08-17 00:34:25 -05:00
|
|
|
let x = -w * this.pageWidth + (0.5 + w) * this.margin
|
|
|
|
let y = -h * this.pageHeight + (0.5 + h) * this.margin
|
|
|
|
|
|
|
|
if (!this.pagesWithContent[h][w]) continue;
|
2022-08-16 00:33:35 -05:00
|
|
|
// if there was no cover page, the first page already exists
|
|
|
|
if (this.settings.coverPage || h+w > 0) {
|
|
|
|
this.pdf.addPage()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await SVGtoPDF(this.pdf, this.svg.outerHTML, x, y, options)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
save() {
|
|
|
|
this.pdf.end();
|
|
|
|
}
|
|
|
|
}
|