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