The size of a new blank page in PDF points and the positions of its grid lines or dots.
How the precision is kept
Paper sizes are whole inches × 72 or millimeters × 72 ÷ 25.4, kept as 64-bit numbers and not rounded to whole points. The grid is centered on the page; each line position is the start plus index × pitch, computed from the index and not by repeated addition. Positions are rounded to 0.01 point when they are written into the page's content.
Calculations under this policy
2 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
The width and height of each paper size in PDF points.
inch = 72 points; mm = 72 ÷ 25.4 points; A4 = 210 mm × 297 mm
72 and 25.4 are the defined values; 72 ÷ 25.4 is one 64-bit quotient and each metric side is one product with it. The sides are not rounded to whole points.
blank.js
lines 21 to 31
MarkupCraft 0.8.1
const IN = 72, MM = 72 / 25.4;
/** Paper sizes, portrait, in PDF points. */
export const PAPERS = {
letter: { w: 8.5 * IN, h: 11 * IN, metric: false },
tabloid: { w: 11 * IN, h: 17 * IN, metric: false }, // Tabloid = ANSI B
'arch-d': { w: 24 * IN, h: 36 * IN, metric: false },
'arch-e': { w: 36 * IN, h: 48 * IN, metric: false },
a4: { w: 210 * MM, h: 297 * MM, metric: true },
a3: { w: 297 * MM, h: 420 * MM, metric: true },
a1: { w: 594 * MM, h: 841 * MM, metric: true },
};
Grid lines and dots
64-bit
How many grid steps fit inside the margins and where each line or dot is drawn.
n = floor((size − 2 × margin) ÷ pitch + 1e-6); start = (size − n × pitch) ÷ 2; line i = start + i × pitch
The 1e-6 added before the floor keeps a count that should be whole from dropping by one through rounding noise. Each coordinate is start + i × pitch and is rounded to 2 decimals by f2 when written, so a drawn line can sit up to 0.005 point from its computed place.
blank.js
lines 56 to 82
MarkupCraft 0.8.1
/** The grid lines or dots as content-stream text, in the page's own (unturned) user space. */
export function gridContent(w, h, grid, metric = false) {
if (grid !== 'dot' && grid !== 'square') return '';
const { step, margin, major } = metric ? GRID_STEP.metric : GRID_STEP.imperial;
const nx = Math.floor((w - 2 * margin) / step + 1e-6), ny = Math.floor((h - 2 * margin) / step + 1e-6);
if (nx < 1 || ny < 1) return '';
const x0 = (w - nx * step) / 2, y0 = (h - ny * step) / 2, x1 = x0 + nx * step, y1 = y0 + ny * step;
const out = ['q'];
if (grid === 'square') {
for (const heavy of [false, true]) {
out.push(heavy ? '0.62 G 0.5 w' : '0.82 G 0.3 w');
for (let i = 0; i <= nx; i++) if ((i % major === 0) === heavy) out.push(f2(x0 + i * step) + ' ' + f2(y0) + ' m ' + f2(x0 + i * step) + ' ' + f2(y1) + ' l');
for (let j = 0; j <= ny; j++) if ((j % major === 0) === heavy) out.push(f2(x0) + ' ' + f2(y0 + j * step) + ' m ' + f2(x1) + ' ' + f2(y0 + j * step) + ' l');
out.push('S');
}
} else {
// small filled squares (zero-length round-capped lines are dropped by some renderers); bigger on the major pitch
out.push('0.55 g');
for (let i = 0; i <= nx; i++) for (let j = 0; j <= ny; j++) {
const d = i % major === 0 && j % major === 0 ? 1.6 : 1;
out.push(f2(x0 + i * step - d / 2) + ' ' + f2(y0 + j * step - d / 2) + ' ' + d + ' ' + d + ' re');
}
out.push('f');
}
out.push('Q');
return out.join('\n');
}
In detail
Method
Imperial: 1/4 inch pitch on a 1/2 inch margin. Metric: 5 mm pitch on a 10 mm margin. Steps per side = floor((size − 2 × margin) ÷ pitch + 1e-6).
Number types
64-bit numbers; grid coordinates are written as text with at most 2 decimals.
Tolerances
1e-6 is added to the step count before the floor (absolute, on a count of steps).
Limits
Grid coordinates in the PDF are rounded to 0.01 point, about 0.0035 mm.
Approach: 64-bit, direct
Every value is a 64-bit number from input to result. Formulas are closed form or a direct solve, and every comparison uses a stated tolerance.