Fix PDF generation not using DPI settings
This commit is contained in:
+57
-63
@@ -14,23 +14,14 @@ export function downloadBlob(blob: Blob, filename: string) {
|
|||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function prepareSVG(
|
export async function prepareSVG(handler: VectraceHandler, imageRender: CanvasImageEx): Promise<Blob> {
|
||||||
handler: VectraceHandler,
|
|
||||||
imageRender: CanvasImageEx
|
|
||||||
): Promise<Blob> {
|
|
||||||
if (imageRender.svg.scale !== imageRender.scale || imageRender.svg.dirty) {
|
if (imageRender.svg.scale !== imageRender.scale || imageRender.svg.dirty) {
|
||||||
handler.redrawSvg(imageRender.id);
|
handler.redrawSvg(imageRender.id);
|
||||||
}
|
}
|
||||||
return new Blob([imageRender.svg.data], { type: "image/svg+xml" });
|
return new Blob([imageRender.svg.data], { type: "image/svg+xml" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGridCells(paperWidth: number, paperHeight: number, grid: string): GridCell[] {
|
||||||
|
|
||||||
function getGridCells(
|
|
||||||
paperWidth: number,
|
|
||||||
paperHeight: number,
|
|
||||||
grid: string
|
|
||||||
): GridCell[] {
|
|
||||||
const cols = grid === "3x3" ? 3 : grid === "2x2" ? 2 : 1;
|
const cols = grid === "3x3" ? 3 : grid === "2x2" ? 2 : 1;
|
||||||
const rows = grid === "3x3" ? 3 : grid === "2x2" ? 2 : 1;
|
const rows = grid === "3x3" ? 3 : grid === "2x2" ? 2 : 1;
|
||||||
const cellW = paperWidth / cols;
|
const cellW = paperWidth / cols;
|
||||||
@@ -51,39 +42,51 @@ function getGridCells(
|
|||||||
return cells;
|
return cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGridCellsMm(paperWidth: number, paperHeight: number, grid: string): GridCell[] {
|
||||||
|
const cols = grid === "3x3" ? 3 : grid === "2x2" ? 2 : 1;
|
||||||
|
const rows = grid === "3x3" ? 3 : grid === "2x2" ? 2 : 1;
|
||||||
|
const cellW = paperWidth / cols;
|
||||||
|
const cellH = paperHeight / rows;
|
||||||
|
const cells: GridCell[] = [];
|
||||||
|
for (let row = 0; row < rows; row++) {
|
||||||
|
for (let col = 0; col < cols; col++) {
|
||||||
|
cells.push({
|
||||||
|
col,
|
||||||
|
row,
|
||||||
|
x: col * cellW,
|
||||||
|
y: row * cellH,
|
||||||
|
w: cellW,
|
||||||
|
h: cellH,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cells;
|
||||||
|
}
|
||||||
|
|
||||||
function createCellPdf(
|
function createCellPdf(handler: VectraceHandler, cellMm: GridCell): jsPDF {
|
||||||
handler: VectraceHandler,
|
const { DPI } = handler.globalSettingsHandler.settings;
|
||||||
cell: GridCell
|
|
||||||
): jsPDF {
|
|
||||||
|
|
||||||
|
const pxToMm = (px: number): number => (px / DPI) * MM_TO_INCH;
|
||||||
|
|
||||||
const doc = new jsPDF({
|
const doc = new jsPDF({
|
||||||
orientation: cell.w > cell.h ? "landscape" : "portrait",
|
orientation: cellMm.w > cellMm.h ? "landscape" : "portrait",
|
||||||
unit: "mm",
|
unit: "mm",
|
||||||
format: [cell.w, cell.h],
|
format: [cellMm.w, cellMm.h],
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const imageObject of handler.imagesRenders) {
|
for (const imageObject of handler.imagesRenders) {
|
||||||
if (!imageObject.visible) continue;
|
if (!imageObject.visible) continue;
|
||||||
|
|
||||||
const imgX = imageObject.x - cell.x;
|
const imgXMm = pxToMm(imageObject.x) - cellMm.x;
|
||||||
const imgY = imageObject.y - cell.y;
|
const imgYMm = pxToMm(imageObject.y) - cellMm.y;
|
||||||
const imgW = imageObject.image.naturalWidth * imageObject.scale;
|
const imgWMm = pxToMm(imageObject.image.naturalWidth * imageObject.scale);
|
||||||
const imgH = imageObject.image.naturalHeight * imageObject.scale;
|
const imgHMm = pxToMm(imageObject.image.naturalHeight * imageObject.scale);
|
||||||
|
|
||||||
const overlapX = imgX + imgW > 0 && imgX < cell.w;
|
const overlapX = imgXMm + imgWMm > 0 && imgXMm < cellMm.w;
|
||||||
const overlapY = imgY + imgH > 0 && imgY < cell.h;
|
const overlapY = imgYMm + imgHMm > 0 && imgYMm < cellMm.h;
|
||||||
if (!overlapX || !overlapY) continue;
|
if (!overlapX || !overlapY) continue;
|
||||||
|
|
||||||
doc.addImage(
|
doc.addImage(imageObject.image, "PNG", imgXMm, imgYMm, imgWMm, imgHMm);
|
||||||
imageObject.image,
|
|
||||||
"PNG",
|
|
||||||
imgX,
|
|
||||||
imgY,
|
|
||||||
imgW,
|
|
||||||
imgH
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
@@ -95,47 +98,44 @@ const gridConfigs: Record<string, number[]> = {
|
|||||||
};
|
};
|
||||||
export function createPdf(handler: VectraceHandler, withGuides: boolean): jsPDF {
|
export function createPdf(handler: VectraceHandler, withGuides: boolean): jsPDF {
|
||||||
const { DPI, paperHeight, paperWidth } = handler.globalSettingsHandler.settings;
|
const { DPI, paperHeight, paperWidth } = handler.globalSettingsHandler.settings;
|
||||||
const width = (paperWidth / MM_TO_INCH) * DPI;
|
|
||||||
const height = (paperHeight / MM_TO_INCH) * DPI;
|
const pxToMm = (px: number): number => (px / DPI) * MM_TO_INCH;
|
||||||
|
|
||||||
const doc = new jsPDF({
|
const doc = new jsPDF({
|
||||||
orientation: paperWidth > paperHeight ? "landscape" : "portrait",
|
orientation: paperWidth > paperHeight ? "landscape" : "portrait",
|
||||||
unit: "mm",
|
unit: "mm",
|
||||||
format: [width, height],
|
format: [paperWidth, paperHeight],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (withGuides) {
|
if (withGuides) {
|
||||||
const setLine = () => {
|
|
||||||
doc.setDrawColor(64, 64, 64);
|
doc.setDrawColor(64, 64, 64);
|
||||||
doc.setLineWidth(1);
|
doc.setLineWidth(0.5);
|
||||||
};
|
|
||||||
const fractions = gridConfigs[handler.globalSettingsHandler.settings.grid];
|
const fractions = gridConfigs[handler.globalSettingsHandler.settings.grid];
|
||||||
if (fractions) {
|
if (fractions) {
|
||||||
setLine();
|
fractions.forEach((f) => {
|
||||||
fractions.forEach(f => {
|
doc.line(paperWidth * f, 0, paperWidth * f, paperHeight);
|
||||||
doc.line(width * f, 0, width * f, height);
|
doc.line(0, paperHeight * f, paperWidth, paperHeight * f);
|
||||||
doc.line(0, height * f, width, height * f);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const imageObject of handler.imagesRenders) {
|
for (const imageObject of handler.imagesRenders) {
|
||||||
if (imageObject.visible) {
|
if (!imageObject.visible) continue;
|
||||||
|
|
||||||
doc.addImage(
|
doc.addImage(
|
||||||
imageObject.image,
|
imageObject.image,
|
||||||
"PNG",
|
"PNG",
|
||||||
imageObject.x,
|
pxToMm(imageObject.x),
|
||||||
imageObject.y,
|
pxToMm(imageObject.y),
|
||||||
imageObject.image.naturalWidth * imageObject.scale,
|
pxToMm(imageObject.image.naturalWidth * imageObject.scale),
|
||||||
imageObject.image.naturalHeight * imageObject.scale
|
pxToMm(imageObject.image.naturalHeight * imageObject.scale),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function createSVGDoc(handler: VectraceHandler) {
|
export function createSVGDoc(handler: VectraceHandler) {
|
||||||
const { paperWidth, paperHeight, DPI } = handler.globalSettingsHandler.settings;
|
const { paperWidth, paperHeight, DPI } = handler.globalSettingsHandler.settings;
|
||||||
const width = (paperWidth / MM_TO_INCH) * DPI;
|
const width = (paperWidth / MM_TO_INCH) * DPI;
|
||||||
@@ -172,7 +172,7 @@ export async function downloadZip(handler: VectraceHandler): Promise<void> {
|
|||||||
canvas.height = render.image.naturalHeight * render.scale;
|
canvas.height = render.image.naturalHeight * render.scale;
|
||||||
ctx.drawImage(render.image, 0, 0, canvas.width, canvas.height);
|
ctx.drawImage(render.image, 0, 0, canvas.width, canvas.height);
|
||||||
const blob = new Promise<Blob>((resolve, reject) => {
|
const blob = new Promise<Blob>((resolve, reject) => {
|
||||||
canvas.toBlob(data => {
|
canvas.toBlob((data) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
resolve(data);
|
resolve(data);
|
||||||
} else {
|
} else {
|
||||||
@@ -204,16 +204,17 @@ export async function downloadZip(handler: VectraceHandler): Promise<void> {
|
|||||||
|
|
||||||
if (grid !== "none") {
|
if (grid !== "none") {
|
||||||
const cells = getGridCells(width, height, grid);
|
const cells = getGridCells(width, height, grid);
|
||||||
|
const cellsMm = getGridCellsMm(paperWidth, paperHeight, grid);
|
||||||
const cellPdfs = mainFolder.folder("cells/pdfs")!;
|
const cellPdfs = mainFolder.folder("cells/pdfs")!;
|
||||||
const cellSvgs = mainFolder.folder("cells/svgs")!;
|
const cellSvgs = mainFolder.folder("cells/svgs")!;
|
||||||
|
|
||||||
for (const cell of cells) {
|
for (let i = 0; i < cells.length; i++) {
|
||||||
const label = `cell-r${cell.row}-c${cell.col}`;
|
const label = `cell-r${cells[i].row}-c${cells[i].col}`;
|
||||||
|
|
||||||
const cellPdf = createCellPdf(handler, cell);
|
const cellPdf = createCellPdf(handler, cellsMm[i]);
|
||||||
cellPdfs.file(`${label}.pdf`, cellPdf.output("blob"));
|
cellPdfs.file(`${label}.pdf`, cellPdf.output("blob"));
|
||||||
|
|
||||||
const cellSvgBlob = await createCellSvg(handler, cell);
|
const cellSvgBlob = await createCellSvg(handler, cells[i]);
|
||||||
cellSvgs.file(`${label}.svg`, cellSvgBlob);
|
cellSvgs.file(`${label}.svg`, cellSvgBlob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,10 +232,7 @@ function collectPaths(node: INode): INode[] {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createCellSvg(
|
export async function createCellSvg(handler: VectraceHandler, cell: GridCell) {
|
||||||
handler: VectraceHandler,
|
|
||||||
cell: GridCell
|
|
||||||
) {
|
|
||||||
const pathElements: string[] = [];
|
const pathElements: string[] = [];
|
||||||
for (const imageObject of handler.imagesRenders) {
|
for (const imageObject of handler.imagesRenders) {
|
||||||
if (!imageObject.visible) continue;
|
if (!imageObject.visible) continue;
|
||||||
@@ -249,11 +247,7 @@ export async function createCellSvg(
|
|||||||
const imgH = imageObject.image.naturalHeight * imageObject.scale;
|
const imgH = imageObject.image.naturalHeight * imageObject.scale;
|
||||||
|
|
||||||
// Does this image even overlap the cell at all?
|
// Does this image even overlap the cell at all?
|
||||||
const overlaps =
|
const overlaps = imgX + imgW > cell.x && imgX < cell.x + cell.w && imgY + imgH > cell.y && imgY < cell.y + cell.h;
|
||||||
imgX + imgW > cell.x &&
|
|
||||||
imgX < cell.x + cell.w &&
|
|
||||||
imgY + imgH > cell.y &&
|
|
||||||
imgY < cell.y + cell.h;
|
|
||||||
|
|
||||||
if (!overlaps) continue;
|
if (!overlaps) continue;
|
||||||
|
|
||||||
@@ -271,7 +265,7 @@ export async function createCellSvg(
|
|||||||
pathElements.push(
|
pathElements.push(
|
||||||
`<g transform="translate(${imgX - cell.x} ${imgY - cell.y})">` +
|
`<g transform="translate(${imgX - cell.x} ${imgY - cell.y})">` +
|
||||||
`<path d="${d}" fill="${fill}" stroke="${stroke}" stroke-width="${strokeWidth}"/>` +
|
`<path d="${d}" fill="${fill}" stroke="${stroke}" stroke-width="${strokeWidth}"/>` +
|
||||||
`</g>`
|
`</g>`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user