Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial stab & functionality of spine marks #109

Merged
merged 12 commits into from
May 7, 2024
55 changes: 45 additions & 10 deletions src/book.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { PAGE_LAYOUTS, PAGE_SIZES } from './constants.js';
import { updatePageLayoutInfo } from './utils/renderUtils.js';
import JSZip from 'jszip';
import { loadConfiguration } from './utils/formUtils.js';
import { drawFoldlines, drawCropmarks, drawSpineMarks } from './utils/drawing.js';
import { drawFoldlines, drawCropmarks, drawSpineMark, drawSigOrderMark } from './utils/drawing.js';
import { calculateDimensions, calculateLayout } from './utils/layout.js';
import { interleavePages, embedPagesInNewPdf } from './utils/pdf.js';

Expand All @@ -21,6 +21,7 @@ import { interleavePages, embedPagesInNewPdf } from './utils/pdf.js';
* @property {string|number} info - page # or 'b'
* @property {boolean} isSigStart
* @property {boolean} isSigEnd
* @property {number} signatureNum - which signature is this page in. 0 based
*/

/**
Expand Down Expand Up @@ -81,6 +82,7 @@ export class Book {
this.flyleafs = configuration.flyleafs;
this.cropmarks = configuration.cropMarks;
this.pdfEdgeMarks = configuration.pdfEdgeMarks;
this.sigOrderMarks = configuration.sigOrderMarks;
this.cutmarks = configuration.cutMarks;
this.format = configuration.sigFormat;
if (configuration.sigFormat === 'standardsig') {
Expand Down Expand Up @@ -308,14 +310,15 @@ export class Book {
this.format == 'customsig'
) {
// Only generate the first signature for preview
const pagesArr = isPreview ? this.rearrangedpages.slice(0, 1) : this.rearrangedpages;
const pagesArr = this.rearrangedpages;
const signatures = [{}];
const makeSignatures = async () => {
const tasks = pagesArr.map(async (pages, i) => {
console.log(pages);
signatures[i] = { name: `${this.filename}_signature${i}` };
[signatures[i].front, signatures[i].back] = await this.createSignatures({
pageIndexDetails: pages,
maxSigCount: pagesArr.length
});
});
await Promise.all(tasks);
Expand All @@ -332,7 +335,8 @@ export class Book {
await Promise.all(tasks);
};
await duplexSignatures();
previewPdf = signatures[0].duplex;
console.log("Shark")
// previewPdf = signatures[0].duplex;
}

if (this.print_file != 'aggregated' && !isPreview) {
Expand All @@ -353,7 +357,7 @@ export class Book {
await saveSignatures();
}

if (this.print_file != 'signatures' && !isPreview) {
if (this.print_file != 'signatures') {
sithel marked this conversation as resolved.
Show resolved Hide resolved
const saveAggregate = async () => {
const aggregate = {
front: !this.duplex ? await PDFDocument.create() : null,
Expand Down Expand Up @@ -399,8 +403,11 @@ export class Book {
this.zip.file(`${this.filename}_typeset.pdf`, pdfBytes);
});
}
console.log("Do I have this? ",aggregate.duplex.getPageCount())
previewPdf = aggregate.duplex
return aggregate
};
await saveAggregate();
var results = await saveAggregate();
}

var rotationMetaInfo =
Expand Down Expand Up @@ -450,14 +457,17 @@ export class Book {
* (conditionally) populates the destPdf and (conditionally) generates the outname PDF
*
* @param {Object} config - object /w the following parameters:
* @param {PageInfo[]} config.pageList : objects that contain 3 values: { isSigStart: boolean, isSigEnd: boolean, info: either the page number or 'b'}
* @param {PageInfo[]} config.pageList : see documentation at top of file
* @param {boolean} config.back : is 'back' of page (boolean)
* @param {boolean} config.alt : alternate pages (boolean)
* @param {number} config.maxSigCount
* @return reference to the new PDF created
*/
async writepages(config) {
console.log("Write pages ", config)
const pagelist = config.pageList;
const back = config.back;
const maxSigCount = config.maxSigCount;
const filteredList = [];
const blankIndices = [];
pagelist.forEach((pageInfo, i) => {
Expand All @@ -467,6 +477,7 @@ export class Book {
blankIndices.push(i);
}
});

const [outPDF, embeddedPages] = await embedPagesInNewPdf(this.managedDoc, filteredList);

blankIndices.forEach((i) => embeddedPages.splice(i, 0, 'b'));
Expand All @@ -482,7 +493,7 @@ export class Book {
let side2flag = back;

while (block_end <= pagelist.length) {
const sigDetails = config.pageList.slice(block_start, block_end);
const sigDetails = pagelist.slice(block_start, block_end);
side2flag = this.draw_block_onto_page({
outPDF: outPDF,
embeddedPages: embeddedPages,
Expand All @@ -492,10 +503,12 @@ export class Book {
papersize: this.papersize,
positions: positions,
cropmarks: this.cropmarks,
sigOrderMarks: this.sigOrderMarks,
pdfEdgeMarks: this.pdfEdgeMarks,
cutmarks: this.cutmarks,
alt: config.alt,
side2flag: side2flag,
maxSigCount: maxSigCount,
});
block_start += offset;
block_end += offset;
Expand All @@ -507,7 +520,8 @@ export class Book {
*
* @param {Object} config - object /w the following parameters:
* @param {string|null} config.outname : name of pdf added to ongoing zip file. Ex: 'signature1duplex.pdf' (or null if no signature file needed)
* @param {PageInfo[]} config.sigDetails : objects that contain 3 values: { isSigStart: boolean, isSigEnd: boolean, info: either the page number or 'b'}
* @param {PageInfo[]} config.sigDetails : see documentation at top of file
* @param {number} config.maxSigCount: Total number of signatures
* @param {boolean} config.side2flag : is 'back' of page (boolean)
* @param {[number, number]} config.papersize : paper size (as [number, number])
* @param {number} config.block_start: Starting page index
Expand All @@ -529,10 +543,13 @@ export class Book {
const outPDF = config.outPDF;
const positions = config.positions;
const foldmarks = config.cropmarks;
const sigOrderMarks = config.sigOrderMarks;
const pdfEdgeMarks = config.pdfEdgeMarks;
const cutmarks = config.cutmarks;
const alt = config.alt;
const maxSigCount = config.maxSigCount
let side2flag = config.side2flag;
console.log("burp I see ",maxSigCount)

const block = config.embeddedPages.slice(block_start, block_end);
const currPage = outPDF.addPage(papersize);
Expand All @@ -541,6 +558,7 @@ export class Book {
? drawFoldlines(side2flag, this.duplexrotate, papersize, this.per_sheet)
: [];
const drawLines = [...cropLines, ...foldLines];
const drawRects = [];

block.forEach((page, i) => {
if (page == 'b' || page === undefined) {
Expand All @@ -558,14 +576,27 @@ export class Book {
console.error('Unexpected type for page: ', page);
}

if (pdfEdgeMarks && (sigDetails[i].isSigStart || sigDetails[i].isSigEnd)) {
drawLines.push(drawSpineMarks(sigDetails[i], positions[i]));
if (sigDetails[i].isSigStart) {
if (pdfEdgeMarks) {
drawLines.push(drawSpineMark(true, positions[i], 5));
}
if (sigOrderMarks) {
drawRects.push(drawSigOrderMark(sigDetails[i], positions[i], maxSigCount, 5, 20));
}
}
else if (sigDetails[i].isSigEnd) {
if (pdfEdgeMarks) {
drawLines.push(drawSpineMark(false, positions[i], 5));
}
}
});

drawLines.forEach((line) => {
currPage.drawLine(line);
});
drawRects.forEach((rect) => {
currPage.drawRectangle(rect);
})

if (alt) {
side2flag = !side2flag;
Expand All @@ -577,20 +608,24 @@ export class Book {
* PDF builder base function for Classic (non-Wacky) layouts. Called by [createoutputfiles]
*
* @param {Object} config
* @param {number} config.maxSigCount
* @param {PageInfo[][]} config.pageIndexDetails : a nested list of objects.
*/
async createSignatures(config) {
console.log("createSignatures ",config)
sithel marked this conversation as resolved.
Show resolved Hide resolved
const pages = config.pageIndexDetails;
const tasks = [
this.writepages({
pageList: pages[0],
back: false,
alt: false,
maxSigCount: config.maxSigCount,
}),
this.writepages({
pageList: pages[1],
back: true,
alt: false,
maxSigCount: config.maxSigCount,
}),
];
const [pdfFront, pdfBack] = await Promise.all(tasks);
Expand Down
9 changes: 9 additions & 0 deletions src/html/page_layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ <h2>Page Layout</h2>
data-balloon-pos="up"
>
<input type="checkbox" name="pdf_edge_marks" /></span
></label><br>
<label
>Add signature order marks (spine)
<span
data-balloon-length="medium"
aria-label="Puts staggered lines down the different signature spines to indicate order"
data-balloon-pos="up"
>
<input type="checkbox" name="sig_order_marks" /></span
></label>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/models/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const schema = z.object({
cropMarks: urlSafe(coercedBoolean).default(false),
cutMarks: urlSafe(coercedBoolean).default(false),
pdfEdgeMarks: urlSafe(coercedBoolean).default(false),
sigOrderMarks: urlSafe(coercedBoolean).default(false),
pageScaling,
pagePositioning,
mainForeEdgePaddingPt: urlSafe(z.coerce.number()).default(0),
Expand Down
15 changes: 11 additions & 4 deletions src/signatures.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,13 @@ export class Signatures {
const newsigs = [];

// Use the booklet class for each signature
this.signaturepagelists.forEach((pagerange) => {
this.signaturepagelists.forEach((pagerange, i) => {
const pagelistdetails = this.booklet(
pagerange,
this.duplex,
this.per_sheet,
this.duplexrotate
this.duplexrotate,
i
);
newsigs.push(pagelistdetails);
});
Expand Down Expand Up @@ -122,8 +123,9 @@ export class Signatures {
* @param {boolean} duplex - Whether both front and back sides go in the same file or not.
* @param {number} per_sheet - number of pages per sheet (front and back combined)
* @param {boolean} duplexrotate - whether to rotate alternating sheets or not.
* @param {number} sig_num - signature number (0 indexed)
*/
booklet(pages, duplex, per_sheet, duplexrotate) {
booklet(pages, duplex, per_sheet, duplexrotate, sig_num) {
const pagelistdetails = duplex ? [[]] : [[], []];
const { front, rotate, back } = BOOKLET_LAYOUTS[per_sheet];

Expand All @@ -139,19 +141,21 @@ export class Signatures {
let front_end = center;
let back_start = center;
let back_end = center + pageblock;

console.log("outside")
while (front_start >= 0 && back_end <= pages.length) {
const front_block = pages.slice(front_start, front_end);
const back_block = pages.slice(back_start, back_end);

const block = [...front_block, ...back_block];

console.log(" ~~~~ SIG NUM "+sig_num+" on "+front_start+" --> "+back_end)
front_config.forEach((pnum) => {
const page = block[pnum - 1]; //page layouts are 1-indexed, not 0-index
pagelistdetails[0].push({
info: page,
isSigStart: front_start == 0 && pnum == 1,
isSigEnd: front_start == 0 && pnum == block.length,
signatureNum: sig_num,
});
});

Expand All @@ -163,11 +167,14 @@ export class Signatures {
info: page,
isSigStart: front_start == 0 && pnum == 1,
isSigEnd: front_start == 0 && pnum == block.length,
signatureNum: sig_num,
});
});

// Update all our counters
console.log("stepa "+front_start)
front_start -= pageblock;
console.log("stepb "+front_start)
front_end -= pageblock;
back_start += pageblock;
back_end += pageblock;
Expand Down
49 changes: 45 additions & 4 deletions src/utils/drawing.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ export function drawCropmarks(papersize, per_sheet) {
}

/**
* @param {import("../book.js").PageInfo} sigDetails - page info object
* @param {boolean} draw_top_mark - true to draw mark at top of PDF, false for bottom of PDF
* @param {import("../book.js").Position} position - position info object
* @param {number} w - width of the line in pts
* @returns {Line}
*/
export function drawSpineMarks(sigDetails, position) {
const w = 5;
export function drawSpineMark(draw_top_mark, position, w) {
let startX, startY, endX, endY;
if (sigDetails.isSigStart) {
if (draw_top_mark) {
[startX, startY] = position.spineMarkTop;
[endX, endY] = position.spineMarkTop;
} else {
Expand Down Expand Up @@ -148,6 +148,47 @@ export function drawSpineMarks(sigDetails, position) {
return drawLineArgs;
}


/**
* @param {import("../book.js").PageInfo} sigDetails - page info object
* @param {import("../book.js").Position} position - position info object
* @param {number} maxSigCount - number of total signatures
* @param {number} w - width of the mark in pts
* @param {number} suggested_h - suggested height of the mark in pts (can be scaled down to fit all marks between PDF top/bottom)
* @returns {Line}
*/
export function drawSigOrderMark(sigDetails, position, maxSigCount, w, suggested_h) {
sithel marked this conversation as resolved.
Show resolved Hide resolved
const top = drawSpineMark(true, position, w);
const bottom = drawSpineMark(false, position, w);

let x = top.start.x
let y = top.start.y

const dist = (position.rotation == 0) ? top.start.y - bottom.start.y : top.start.x - bottom.start.x
let h = Math.min(suggested_h, dist/maxSigCount)
const offset = h * sigDetails.signatureNum;
console.log("Looking at signature ",sigDetails.signatureNum," of ",maxSigCount," PDF top/bottom distance ",dist," results in ",h," (",suggested_h," vs ",(dist/maxSigCount),") order mark height w/ offset ",offset," (width ",w,")")

if (position.rotation == 0) {
h = h * -1;
y -= offset;
} else {
const temp = h;
h = w;
w = temp * -1;
x -= offset
}

return {
x: x,
y: y,
width: w,
height: h,
borderWidth: 0,
color: rgb(0, 0, 0),
opacity: 0.5,
};
}
/**
* @param {number} x
* @param {number} ystart
Expand Down
1 change: 1 addition & 0 deletions src/utils/formUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const fromFormToConfiguration = (form) =>
paperRotation90: form.has('paper_rotation_90'),
pageLayout: form.get('pagelayout'),
cropMarks: form.has('cropmarks'),
sigOrderMarks: form.has('sig_order_marks'),
pdfEdgeMarks: form.has('pdf_edge_marks'),
cutMarks: form.has('cutmarks'),
pageScaling: form.get('page_scaling'),
Expand Down
4 changes: 4 additions & 0 deletions src/utils/renderUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ export function renderFormFromSettings(configuration) {
document.querySelector("input[name='cropmarks']").checked = true;
}

if (configuration.sigOrderMarks) {
document.querySelector("input[name='sig_order_marks']").checked = true;
}

if (configuration.pdfEdgeMarks) {
document.querySelector("input[name='pdf_edge_marks']").checked = true;
}
Expand Down
Loading