diff --git a/index.html b/index.html
index 250b012..f570ac6 100644
--- a/index.html
+++ b/index.html
@@ -33,6 +33,7 @@
White Space Manipulation. All values are in points, relative to original document.
1
diff --git a/src/main.js b/src/main.js
index 5a1b15c..0a97b9a 100644
--- a/src/main.js
+++ b/src/main.js
@@ -9,6 +9,7 @@ import {
handleGenerateClick,
handlePreviewClick,
handleResetSettingsClick,
+ handleSewingMarksCheckboxState,
} from './utils/clickHandlers.js';
import { renderPaperSelectOptions } from './utils/renderUtils.js';
@@ -25,6 +26,7 @@ window.addEventListener('DOMContentLoaded', () => {
const fileInput = document.getElementById('input_file');
const inputs = document.querySelectorAll('input, select');
const sourceRotation = document.getElementById('source_rotation');
+ const sewingMarks = document.getElementById('add_sewing_marks_checkbox');
const sourceRotationExamples = Array.from(
document.getElementsByClassName('source_rotation_example')
);
@@ -53,4 +55,8 @@ window.addEventListener('DOMContentLoaded', () => {
example.style.display = example.id === selectedValue ? 'block' : 'none';
});
});
+ sewingMarks.addEventListener('change', (e) => {
+ const willBeEnabled = e.srcElement.checked;
+ handleSewingMarksCheckboxState(willBeEnabled);
+ });
});
diff --git a/src/models/configuration.js b/src/models/configuration.js
index 0dde7b5..4006aae 100644
--- a/src/models/configuration.js
+++ b/src/models/configuration.js
@@ -35,6 +35,10 @@ const sourceRotation = urlSafe(
z.enum(['none', '90cw', '90ccw', 'out_binding', 'in_binding'])
).default('none');
+const sewingMarkLocation = urlSafe(z.enum(['all', 'only_out', 'only_in', 'in_n_out'])).default(
+ 'all'
+);
+
/** @type { keyof typeof import("../constants").PAGE_SIZES } */
const availablePaperSizes = Object.keys(PAGE_SIZES);
@@ -82,6 +86,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),
@@ -96,6 +101,7 @@ export const schema = z.object({
flyleafs: urlSafe(z.coerce.number()).default(1),
sewingMarksEnabled: urlSafe(coercedBoolean).default(false),
+ sewingMarkLocation,
sewingMarksMarginPt: urlSafe(z.coerce.number()).default(72),
sewingMarksAmount: urlSafe(z.coerce.number()).default(3),
sewingMarksTapeWidthPt: urlSafe(z.coerce.number()).default(36),
diff --git a/src/signatures.js b/src/signatures.js
index 4a35528..7bf27c5 100644
--- a/src/signatures.js
+++ b/src/signatures.js
@@ -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);
});
@@ -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];
@@ -146,24 +148,40 @@ export class Signatures {
const block = [...front_block, ...back_block];
+ console.log(
+ `Looking front_config : block.length ${block.length} : given center ${center}, front_start ${front_start} - front_end ${front_end}, back_start ${back_start} - back_end ${back_end}, pages.length ${pages.length}`
+ );
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,
+ isSigMiddle: front_end == back_start && block.length / 2 + 1 == pnum,
+ signatureNum: sig_num,
});
+ console.log(
+ ` >> ${pnum} :: ${page} :: ${front_end == back_start && block.length / 2 + 1 == pnum}`
+ );
});
const backlist = this.duplex ? 0 : 1;
+ console.log(
+ `Looking back_config : given center ${center}, front_start ${front_start} - front_end ${front_end}, back_start ${back_start} - back_end ${back_end}, pages.length ${pages.length}`
+ );
back_config.forEach((pnum) => {
const page = block[pnum - 1];
pagelistdetails[backlist].push({
info: page,
isSigStart: front_start == 0 && pnum == 1,
isSigEnd: front_start == 0 && pnum == block.length,
+ isSigMiddle: front_end == back_start && block.length / 2 + 1 == pnum,
+ signatureNum: sig_num,
});
+ console.log(
+ ` >> ${pnum} :: ${page} :: ${front_end == back_start && block.length / 2 + 1 == pnum}`
+ );
});
// Update all our counters
diff --git a/src/utils/clickHandlers.js b/src/utils/clickHandlers.js
index 6c6e3a0..5517581 100644
--- a/src/utils/clickHandlers.js
+++ b/src/utils/clickHandlers.js
@@ -53,3 +53,12 @@ export function handleResetSettingsClick(book) {
updateAddOrRemoveCustomPaperOption();
updatePaperSelectOptionsUnits();
}
+
+export function handleSewingMarksCheckboxState(sewingMarksEnabled) {
+ const sewingMarkDetailsEl = document.getElementById('sewing_marks_details');
+ if (sewingMarksEnabled) {
+ sewingMarkDetailsEl.setAttribute('open', 0);
+ } else {
+ sewingMarkDetailsEl.removeAttribute('open');
+ }
+}
diff --git a/src/utils/drawing.js b/src/utils/drawing.js
index afeb25c..3cd62a1 100644
--- a/src/utils/drawing.js
+++ b/src/utils/drawing.js
@@ -124,12 +124,20 @@ export function drawCropmarks(papersize, per_sheet) {
/**
* @param {@param {import("../book.js").PageInfo}} sigDetails - information about signature where marks will be printed
* @param {import("../book.js").Position} position - position info object
+ * @param sewingMarkLocation - see ./models/configuration.js for possible values
* @param {number} amount - amount of sewing crosses.
* @param {number} marginPt - distance from the end of sheet of paper to kettle mark
* @param {number} tapeWidthPt - distance between two points in a single sewwing cross.
* @returns {Point[]}
*/
-export function drawSewingMarks(sigDetails, position, amount, marginPt, tapeWidthPt) {
+export function drawSewingMarks(
+ sigDetails,
+ position,
+ sewingMarkLocation,
+ amount,
+ marginPt,
+ tapeWidthPt
+) {
// Here normalize coordinates to always think in x an y like this
// | P |H| P |
// | A |E| A |
@@ -139,7 +147,17 @@ export function drawSewingMarks(sigDetails, position, amount, marginPt, tapeWidt
// |-POSITION-| | |
// Left pages have spine position on the edge :/
+ console.log('try to draw');
if (position.isLeftPage) return [];
+ console.log(' on right');
+
+ if (sewingMarkLocation == 'only_out' && !sigDetails.isSigStart) return [];
+ console.log(' a');
+ if (sewingMarkLocation == 'only_in' && !sigDetails.isSigMiddle) return [];
+ console.log(' b');
+ if (sewingMarkLocation == 'in_n_out' && !(sigDetails.isSigStart || sigDetails.isSigMiddle))
+ return [];
+ console.log(' c');
var arePageRotated = Math.abs(position.rotation) === 90;
let totalSpineHeight = 0;
@@ -188,14 +206,14 @@ export function drawSewingMarks(sigDetails, position, amount, marginPt, tapeWidt
}
/**
- * @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 {
@@ -223,6 +241,48 @@ export function drawSpineMarks(sigDetails, position) {
return drawLineArgs;
}
+/**
+ * TODO : these params should probably be pushed into a config... maybe next time/next pass
+ *
+ * @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) {
+ 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
diff --git a/src/utils/formUtils.js b/src/utils/formUtils.js
index 1766dc9..89618a6 100644
--- a/src/utils/formUtils.js
+++ b/src/utils/formUtils.js
@@ -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'),
@@ -41,7 +42,8 @@ const fromFormToConfiguration = (form) =>
paperSizeCustomWidth: form.get('paper_size_custom_width'),
paperSizeCustomHeight: form.get('paper_size_custom_height'),
- sewingMarksEnabled: form.get('add_sewing_marks_checkbox'),
+ sewingMarksEnabled: form.has('add_sewing_marks_checkbox'),
+ sewingMarkLocation: form.get('sewing_mark_locations'),
sewingMarksMarginPt: form.get('sewing_marks_margin_pt'),
sewingMarksAmount: form.get('sewing_marks_amount'),
sewingMarksTapeWidthPt: form.get('sewing_marks_tape_width_pt'),
diff --git a/src/utils/layout.js b/src/utils/layout.js
index a040371..033792f 100644
--- a/src/utils/layout.js
+++ b/src/utils/layout.js
@@ -131,7 +131,7 @@ export function calculateDimensions(book) {
top: padding_pt.top * sy,
};
- // page_positioning has 2 options: centered, binding_alinged
+ // page_positioning has 2 options: centered, binding_aligned
const positioning = page_positioning;
const xForeEdgeShiftFunc = function () {
diff --git a/src/utils/renderUtils.js b/src/utils/renderUtils.js
index 1c8b299..101d378 100644
--- a/src/utils/renderUtils.js
+++ b/src/utils/renderUtils.js
@@ -3,6 +3,7 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
import { PAGE_SIZES } from '../constants';
+import { handleSewingMarksCheckboxState } from './clickHandlers.js';
export function renderPageCount(book) {
const pageCount = document.getElementById('page_count');
@@ -183,6 +184,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;
}
@@ -199,8 +204,11 @@ export function renderFormFromSettings(configuration) {
).checked = true;
// Set french link stitches settings
+ handleSewingMarksCheckboxState(configuration.sewingMarksEnabled);
document.querySelector('input[name="add_sewing_marks_checkbox"]').checked =
configuration.sewingMarksEnabled;
+ document.querySelector('select[name="sewing_mark_locations"]').value =
+ configuration.sewingMarkLocation;
document.querySelector('input[name="sewing_marks_margin_pt"]').value =
configuration.sewingMarksMarginPt;
document.querySelector('input[name="sewing_marks_amount"]').value =