Shrink ignores what cannot be seen; blank lines at a block's end go
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
bb41047e85
commit
56ab259cd4
5 files changed
+158
-11
No files matched your search
+43
-9
@@ -184,6 +184,17 @@ export function cleanText(received) {
|
||||
};
|
||||
}
|
||||
|
||||
/** The paper's colour, in which a mark cannot be seen. */
|
||||
export const PAPER_WHITE = '#ffffff';
|
||||
|
||||
/**
|
||||
* @param {string} color
|
||||
* @returns {boolean} Whether a mark of this colour is invisible on the paper.
|
||||
*/
|
||||
export function isPaperWhite(color) {
|
||||
return color.trim().toLowerCase() === PAPER_WHITE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rectangle a text block takes up: its own, grown to its lines, for a
|
||||
* text rectangle; the lines' box for free text.
|
||||
@@ -550,20 +561,43 @@ export class Page {
|
||||
* @returns {Rectangle | null} Null if the page is blank.
|
||||
*/
|
||||
contentSheet() {
|
||||
/** @type {Rectangle | null} */
|
||||
let box = this.strokeBounds ? { ...this.strokeBounds } : null;
|
||||
for (const item of [...this.images, ...this.hides]) {
|
||||
// What can be seen (Andy, 2026-10-14): a stroke or free text in the
|
||||
// paper's white is left out (over an image it shows, but lies within
|
||||
// the image's box, which counts); a text rectangle counts whole, its
|
||||
// red frame being visible. The record that grows the page while
|
||||
// writing (strokeBounds) is not used here, so a white stroke still
|
||||
// gets room as it is written.
|
||||
/** @type {{box: Rectangle | null}} A holder, since the closure's assignments are not seen by the type checker. */
|
||||
const found = { box: null };
|
||||
/** @param {number} left @param {number} top @param {number} width @param {number} height */
|
||||
const add = (left, top, width, height) => {
|
||||
const box = found.box;
|
||||
if (!box) {
|
||||
box = { left: item.x, top: item.y, width: item.width, height: item.height };
|
||||
continue;
|
||||
found.box = { left, top, width, height };
|
||||
return;
|
||||
}
|
||||
const right = Math.max(box.left + box.width, item.x + item.width);
|
||||
const bottom = Math.max(box.top + box.height, item.y + item.height);
|
||||
box.left = Math.min(box.left, item.x);
|
||||
box.top = Math.min(box.top, item.y);
|
||||
const right = Math.max(box.left + box.width, left + width);
|
||||
const bottom = Math.max(box.top + box.height, top + height);
|
||||
box.left = Math.min(box.left, left);
|
||||
box.top = Math.min(box.top, top);
|
||||
box.width = right - box.left;
|
||||
box.height = bottom - box.top;
|
||||
};
|
||||
for (const layer of this.layers.values()) {
|
||||
for (const stroke of layer.strokes.values()) {
|
||||
if (isPaperWhite(stroke.color)) continue;
|
||||
const reach = stroke.width * 2; // As includeStroke reckons it.
|
||||
const p = stroke.points;
|
||||
for (let i = 0; i < p.length; i += POINT_SIZE) add(p[i] - reach, p[i + 1] - reach, 2 * reach, 2 * reach);
|
||||
}
|
||||
for (const block of layer.texts.values()) {
|
||||
if (block.height === null && isPaperWhite(block.color)) continue;
|
||||
const b = textBounds(block);
|
||||
add(b.left, b.top, b.width, b.height);
|
||||
}
|
||||
}
|
||||
for (const item of [...this.images, ...this.hides]) add(item.x, item.y, item.width, item.height);
|
||||
const box = found.box;
|
||||
if (!box) return null;
|
||||
// The greater of the two margins (Andy, 2026-10-08), exactly, the same
|
||||
// on all four sides (a grid made them uneven, Andy, 2026-10-08).
|
||||
|
||||
Reference in new issue
Block a user