documents.js 1.60.3 → 1.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -44
- package/dist/{blr-types-CYYC3yYU.d.cts → blr-types-DVgO1DQ9.d.cts} +1 -1
- package/dist/{blr-types-CYYC3yYU.d.ts → blr-types-DVgO1DQ9.d.ts} +1 -1
- package/dist/convert/capability.cjs +1 -0
- package/dist/convert/capability.d.cts +1 -1
- package/dist/convert/capability.d.ts +1 -1
- package/dist/convert/capability.js +1 -0
- package/dist/convert/convert.cjs +29 -27
- package/dist/convert/convert.d.cts +9 -3
- package/dist/convert/convert.d.ts +9 -3
- package/dist/convert/convert.js +29 -27
- package/dist/edit/docx/content.cjs +75 -13
- package/dist/edit/docx/content.d.cts +8 -2
- package/dist/edit/docx/content.d.ts +8 -2
- package/dist/edit/docx/content.js +75 -13
- package/dist/edit/docx/paragraph.cjs +14 -0
- package/dist/edit/docx/paragraph.d.cts +5 -0
- package/dist/edit/docx/paragraph.d.ts +5 -0
- package/dist/edit/docx/paragraph.js +14 -0
- package/dist/edit/docx/run.cjs +1 -1
- package/dist/edit/docx/run.js +1 -1
- package/dist/edit/docx/table.cjs +41 -0
- package/dist/edit/docx/table.d.cts +7 -1
- package/dist/edit/docx/table.d.ts +7 -1
- package/dist/edit/docx/table.js +42 -1
- package/dist/edit/geometry.cjs +38 -0
- package/dist/edit/geometry.d.cts +7 -0
- package/dist/edit/geometry.d.ts +7 -0
- package/dist/edit/geometry.js +36 -0
- package/dist/edit/odg/content.cjs +15 -12
- package/dist/edit/odg/content.js +15 -12
- package/dist/edit/odg/editor.d.cts +1 -1
- package/dist/edit/odg/editor.d.ts +1 -1
- package/dist/edit/odg/page.d.cts +3 -3
- package/dist/edit/odg/page.d.ts +3 -3
- package/dist/edit/odg/vector.cjs +22 -13
- package/dist/edit/odg/vector.d.cts +1 -1
- package/dist/edit/odg/vector.d.ts +1 -1
- package/dist/edit/odg/vector.js +23 -14
- package/dist/edit/odp/content.cjs +15 -0
- package/dist/edit/odp/content.js +16 -1
- package/dist/edit/odp/editor.d.cts +1 -1
- package/dist/edit/odp/editor.d.ts +1 -1
- package/dist/edit/odp/image.d.cts +1 -1
- package/dist/edit/odp/image.d.ts +1 -1
- package/dist/edit/odp/shape.cjs +11 -30
- package/dist/edit/odp/shape.d.cts +2 -2
- package/dist/edit/odp/shape.d.ts +2 -2
- package/dist/edit/odp/shape.js +13 -33
- package/dist/edit/odp/slide.cjs +11 -0
- package/dist/edit/odp/slide.d.cts +14 -4
- package/dist/edit/odp/slide.d.ts +14 -4
- package/dist/edit/odp/slide.js +12 -1
- package/dist/edit/odt/content.cjs +56 -16
- package/dist/edit/odt/content.d.cts +4 -2
- package/dist/edit/odt/content.d.ts +4 -2
- package/dist/edit/odt/content.js +56 -17
- package/dist/edit/odt/editor.d.cts +1 -1
- package/dist/edit/odt/editor.d.ts +1 -1
- package/dist/edit/odt/table.cjs +36 -0
- package/dist/edit/odt/table.d.cts +1 -36
- package/dist/edit/odt/table.d.ts +1 -36
- package/dist/edit/odt/table.js +37 -1
- package/dist/edit/pptx/content.cjs +71 -3
- package/dist/edit/pptx/content.js +71 -3
- package/dist/edit/pptx/editor.d.cts +1 -1
- package/dist/edit/pptx/editor.d.ts +1 -1
- package/dist/edit/pptx/image.d.cts +1 -1
- package/dist/edit/pptx/image.d.ts +1 -1
- package/dist/edit/pptx/shape.cjs +23 -1
- package/dist/edit/pptx/shape.d.cts +2 -2
- package/dist/edit/pptx/shape.d.ts +2 -2
- package/dist/edit/pptx/shape.js +23 -3
- package/dist/edit/pptx/slide.cjs +10 -1
- package/dist/edit/pptx/slide.d.cts +11 -4
- package/dist/edit/pptx/slide.d.ts +11 -4
- package/dist/edit/pptx/slide.js +10 -1
- package/dist/edit/pptx/table.cjs +136 -0
- package/dist/edit/pptx/table.d.cts +2 -0
- package/dist/edit/pptx/table.d.ts +2 -0
- package/dist/edit/pptx/table.js +131 -0
- package/dist/firebird/backup.d.cts +1 -1
- package/dist/firebird/backup.d.ts +1 -1
- package/dist/firebird/blr-types.cjs +2 -2
- package/dist/firebird/blr-types.d.cts +1 -1
- package/dist/firebird/blr-types.d.ts +1 -1
- package/dist/firebird/blr-types.js +2 -2
- package/dist/firebird/data.cjs +68 -14
- package/dist/firebird/data.d.cts +1 -1
- package/dist/firebird/data.d.ts +1 -1
- package/dist/firebird/data.js +68 -14
- package/dist/firebird/schema.cjs +13 -1
- package/dist/firebird/schema.d.cts +1 -1
- package/dist/firebird/schema.d.ts +1 -1
- package/dist/firebird/schema.js +13 -1
- package/dist/{geometry-DvwdrIij.d.cts → geometry-DaJr8yQW.d.cts} +2 -2
- package/dist/{geometry-DvwdrIij.d.ts → geometry-DaJr8yQW.d.ts} +2 -2
- package/dist/hsqldb/binary-script.cjs +154 -0
- package/dist/hsqldb/binary-script.d.cts +15 -0
- package/dist/hsqldb/binary-script.d.ts +15 -0
- package/dist/hsqldb/binary-script.js +151 -0
- package/dist/hsqldb/cache.cjs +18 -11
- package/dist/hsqldb/cache.d.cts +9 -4
- package/dist/hsqldb/cache.d.ts +9 -4
- package/dist/hsqldb/cache.js +18 -11
- package/dist/hsqldb/rowformat.cjs +60 -16
- package/dist/hsqldb/rowformat.d.cts +2 -21
- package/dist/hsqldb/rowformat.d.ts +2 -21
- package/dist/hsqldb/rowformat.js +60 -17
- package/dist/{image-BZDy72Jb.d.cts → image-7snmKIxn.d.cts} +1 -1
- package/dist/{image-B-xQWYYS.d.ts → image-Cs8xF753.d.ts} +1 -1
- package/dist/{image-CeqwL-Qs.d.ts → image-DHcA9kaK.d.ts} +1 -1
- package/dist/{image-DWX6cNOD.d.cts → image-M5SezZVI.d.cts} +1 -1
- package/dist/index.cjs +54 -3
- package/dist/index.d.cts +28 -20
- package/dist/index.d.ts +27 -19
- package/dist/index.js +13 -4
- package/dist/layout/cell-typing.cjs +209 -0
- package/dist/layout/cell-typing.d.cts +22 -0
- package/dist/layout/cell-typing.d.ts +22 -0
- package/dist/layout/cell-typing.js +208 -0
- package/dist/layout/drawing.cjs +193 -17
- package/dist/layout/drawing.js +193 -17
- package/dist/layout/engine.cjs +46 -29
- package/dist/layout/engine.d.cts +0 -2
- package/dist/layout/engine.d.ts +0 -2
- package/dist/layout/engine.js +47 -30
- package/dist/layout/lattice.cjs +139 -0
- package/dist/layout/lattice.d.cts +20 -0
- package/dist/layout/lattice.d.ts +20 -0
- package/dist/layout/lattice.js +135 -0
- package/dist/layout/reconstruct.cjs +176 -113
- package/dist/layout/reconstruct.d.cts +2 -0
- package/dist/layout/reconstruct.d.ts +2 -0
- package/dist/layout/reconstruct.js +173 -110
- package/dist/layout/shared.cjs +52 -0
- package/dist/layout/shared.d.cts +4 -2
- package/dist/layout/shared.d.ts +4 -2
- package/dist/layout/shared.js +51 -1
- package/dist/layout/sheets.cjs +45 -11
- package/dist/layout/sheets.js +46 -12
- package/dist/layout/slides.cjs +7 -7
- package/dist/layout/slides.d.cts +0 -3
- package/dist/layout/slides.d.ts +0 -3
- package/dist/layout/slides.js +7 -7
- package/dist/markdown/write.cjs +19 -6
- package/dist/markdown/write.js +19 -6
- package/dist/mathml/layout.cjs +43 -9
- package/dist/mathml/layout.d.cts +1 -1
- package/dist/mathml/layout.d.ts +1 -1
- package/dist/mathml/layout.js +43 -9
- package/dist/mathml/variant.cjs +48 -5
- package/dist/mathml/variant.js +48 -5
- package/dist/model/embedded-drawing.cjs +32 -0
- package/dist/model/embedded-drawing.d.cts +8 -0
- package/dist/model/embedded-drawing.d.ts +8 -0
- package/dist/model/embedded-drawing.js +30 -0
- package/dist/model/formula.cjs +31 -0
- package/dist/model/formula.d.cts +6 -6
- package/dist/model/formula.d.ts +6 -6
- package/dist/model/formula.js +27 -0
- package/dist/model/geometry.d.cts +1 -1
- package/dist/model/geometry.d.ts +1 -1
- package/dist/model/paint-order.cjs +15 -0
- package/dist/model/paint-order.d.cts +14 -0
- package/dist/model/paint-order.d.ts +14 -0
- package/dist/model/paint-order.js +14 -0
- package/dist/odb/components.cjs +12 -0
- package/dist/odb/components.d.cts +6 -0
- package/dist/odb/components.d.ts +6 -0
- package/dist/odb/components.js +10 -0
- package/dist/odb/read.cjs +11 -7
- package/dist/odb/read.d.cts +3 -2
- package/dist/odb/read.d.ts +3 -2
- package/dist/odb/read.js +11 -7
- package/dist/odf/formula/detect.cjs +86 -18
- package/dist/odf/formula/detect.d.cts +10 -6
- package/dist/odf/formula/detect.d.ts +10 -6
- package/dist/odf/formula/detect.js +86 -19
- package/dist/odf/formula/read.cjs +4 -16
- package/dist/odf/formula/read.d.cts +4 -8
- package/dist/odf/formula/read.d.ts +4 -8
- package/dist/odf/formula/read.js +5 -17
- package/dist/odf/odp/read.cjs +9 -19
- package/dist/odf/odp/read.d.cts +2 -7
- package/dist/odf/odp/read.d.ts +2 -7
- package/dist/odf/odp/read.js +10 -20
- package/dist/odf/odt/read.cjs +63 -23
- package/dist/odf/odt/read.d.cts +2 -7
- package/dist/odf/odt/read.d.ts +2 -7
- package/dist/odf/odt/read.js +64 -24
- package/dist/omml/write.cjs +258 -0
- package/dist/omml/write.d.cts +2 -0
- package/dist/omml/write.d.ts +2 -0
- package/dist/omml/write.js +256 -0
- package/dist/rowformat-Cl2exlEh.d.cts +25 -0
- package/dist/rowformat-Cl2exlEh.d.ts +25 -0
- package/dist/{schema-Acco3Ezi.d.cts → schema-BeR_KJ0X.d.cts} +3 -1
- package/dist/{schema-VkAA6pF5.d.ts → schema-CSKwSb_v.d.ts} +3 -1
- package/dist/{shape-BUfjw5eZ.d.cts → shape-BhkP6HB8.d.cts} +6 -2
- package/dist/{shape-CTkl6kt8.d.ts → shape-BkVcwPcf.d.ts} +6 -2
- package/dist/{shape-BfN3m52m.d.ts → shape-CVXedeL7.d.ts} +3 -2
- package/dist/{shape-CN2ycxOo.d.cts → shape-CXZ6fejV.d.cts} +3 -2
- package/dist/table-C3CPZ--2.d.cts +35 -0
- package/dist/table-DjYcNOFm.d.cts +44 -0
- package/dist/table-DqfqMkVq.d.ts +44 -0
- package/dist/table-DvS_7UQS.d.ts +35 -0
- package/dist/{vector-ClohqsOe.d.cts → vector-Puuqu_IT.d.cts} +4 -0
- package/dist/{vector-ClohqsOe.d.ts → vector-Puuqu_IT.d.ts} +4 -0
- package/dist/write-DuyfnbL_.d.cts +16 -0
- package/dist/write-Zqwx6pka.d.ts +16 -0
- package/package.json +4 -4
- package/dist/odf/formula/placeholder.cjs +0 -36
- package/dist/odf/formula/placeholder.d.cts +0 -14
- package/dist/odf/formula/placeholder.d.ts +0 -14
- package/dist/odf/formula/placeholder.js +0 -36
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/layout/lattice.ts
|
|
3
|
+
function extractLineCandidates(items) {
|
|
4
|
+
const segments = [];
|
|
5
|
+
for (const item of items) {
|
|
6
|
+
if (item.kind === "line") {
|
|
7
|
+
segments.push({
|
|
8
|
+
item,
|
|
9
|
+
x1Pt: item.x1Pt,
|
|
10
|
+
y1Pt: item.y1Pt,
|
|
11
|
+
x2Pt: item.x2Pt,
|
|
12
|
+
y2Pt: item.y2Pt
|
|
13
|
+
});
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (item.kind === "path" && item.stroke !== void 0 && item.subpaths.length === 1) {
|
|
17
|
+
const subpath = item.subpaths[0];
|
|
18
|
+
if (subpath.segments.length === 1 && subpath.segments[0].kind === "line") {
|
|
19
|
+
const segment = subpath.segments[0];
|
|
20
|
+
segments.push({
|
|
21
|
+
item,
|
|
22
|
+
x1Pt: subpath.startXPt,
|
|
23
|
+
y1Pt: subpath.startYPt,
|
|
24
|
+
x2Pt: segment.xPt,
|
|
25
|
+
y2Pt: segment.yPt
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return segments;
|
|
31
|
+
}
|
|
32
|
+
const AXIS_ALIGNMENT_TOLERANCE_PT = .5;
|
|
33
|
+
const MIN_GRIDLINE_LENGTH_PT = 4;
|
|
34
|
+
function classifyAxisLine(seg) {
|
|
35
|
+
const dx = Math.abs(seg.x2Pt - seg.x1Pt);
|
|
36
|
+
const dy = Math.abs(seg.y2Pt - seg.y1Pt);
|
|
37
|
+
if (dy <= AXIS_ALIGNMENT_TOLERANCE_PT && dx >= MIN_GRIDLINE_LENGTH_PT) return {
|
|
38
|
+
axis: "horizontal",
|
|
39
|
+
position: (seg.y1Pt + seg.y2Pt) / 2,
|
|
40
|
+
startPt: Math.min(seg.x1Pt, seg.x2Pt),
|
|
41
|
+
endPt: Math.max(seg.x1Pt, seg.x2Pt),
|
|
42
|
+
item: seg.item
|
|
43
|
+
};
|
|
44
|
+
if (dx <= AXIS_ALIGNMENT_TOLERANCE_PT && dy >= MIN_GRIDLINE_LENGTH_PT) return {
|
|
45
|
+
axis: "vertical",
|
|
46
|
+
position: (seg.x1Pt + seg.x2Pt) / 2,
|
|
47
|
+
startPt: Math.min(seg.y1Pt, seg.y2Pt),
|
|
48
|
+
endPt: Math.max(seg.y1Pt, seg.y2Pt),
|
|
49
|
+
item: seg.item
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const POSITION_DEDUPE_TOLERANCE_PT = .5;
|
|
53
|
+
function longestContiguousSpan(segments) {
|
|
54
|
+
const sorted = [...segments].sort((a, b) => a.startPt - b.startPt);
|
|
55
|
+
let bestStart = sorted[0].startPt;
|
|
56
|
+
let bestEnd = sorted[0].endPt;
|
|
57
|
+
let runStart = sorted[0].startPt;
|
|
58
|
+
let runEnd = sorted[0].endPt;
|
|
59
|
+
for (const segment of sorted.slice(1)) {
|
|
60
|
+
if (segment.startPt <= runEnd + POSITION_DEDUPE_TOLERANCE_PT) runEnd = Math.max(runEnd, segment.endPt);
|
|
61
|
+
else {
|
|
62
|
+
runStart = segment.startPt;
|
|
63
|
+
runEnd = segment.endPt;
|
|
64
|
+
}
|
|
65
|
+
if (runEnd - runStart > bestEnd - bestStart) {
|
|
66
|
+
bestStart = runStart;
|
|
67
|
+
bestEnd = runEnd;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
spanPt: bestEnd - bestStart,
|
|
72
|
+
startPt: bestStart,
|
|
73
|
+
endPt: bestEnd
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function dedupeAxisLines(segments, descending) {
|
|
77
|
+
const sorted = [...segments].sort((a, b) => descending ? b.position - a.position : a.position - b.position);
|
|
78
|
+
const groups = [];
|
|
79
|
+
for (const candidate of sorted) {
|
|
80
|
+
const last = groups[groups.length - 1];
|
|
81
|
+
if (last !== void 0 && Math.abs(candidate.position - last[0].position) <= POSITION_DEDUPE_TOLERANCE_PT) last.push(candidate);
|
|
82
|
+
else groups.push([candidate]);
|
|
83
|
+
}
|
|
84
|
+
return groups.map((group) => {
|
|
85
|
+
const { spanPt, startPt, endPt } = longestContiguousSpan(group);
|
|
86
|
+
return {
|
|
87
|
+
position: group[0].position,
|
|
88
|
+
spanPt,
|
|
89
|
+
startPt,
|
|
90
|
+
endPt,
|
|
91
|
+
items: group.map((segment) => segment.item)
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const MIN_GRIDLINE_COUNT_PER_AXIS = 3;
|
|
96
|
+
const GRID_SPAN_CONSISTENCY_RATIO = .9;
|
|
97
|
+
function consistentLines(lines) {
|
|
98
|
+
if (lines.length < MIN_GRIDLINE_COUNT_PER_AXIS) return [];
|
|
99
|
+
const maxSpanPt = Math.max(...lines.map((l) => l.spanPt));
|
|
100
|
+
const consistent = lines.filter((l) => l.spanPt >= maxSpanPt * GRID_SPAN_CONSISTENCY_RATIO);
|
|
101
|
+
return consistent.length >= MIN_GRIDLINE_COUNT_PER_AXIS ? consistent : [];
|
|
102
|
+
}
|
|
103
|
+
function detectGridLattice(items) {
|
|
104
|
+
const horizontal = [];
|
|
105
|
+
const vertical = [];
|
|
106
|
+
for (const seg of extractLineCandidates(items)) {
|
|
107
|
+
const classified = classifyAxisLine(seg);
|
|
108
|
+
if (classified === void 0) continue;
|
|
109
|
+
(classified.axis === "horizontal" ? horizontal : vertical).push(classified);
|
|
110
|
+
}
|
|
111
|
+
const rowBoundaries = consistentLines(dedupeAxisLines(horizontal, true));
|
|
112
|
+
const columnBoundaries = consistentLines(dedupeAxisLines(vertical, false));
|
|
113
|
+
if (rowBoundaries.length === 0 || columnBoundaries.length === 0) return;
|
|
114
|
+
const sourceItems = /* @__PURE__ */ new Set();
|
|
115
|
+
for (const line of [...rowBoundaries, ...columnBoundaries]) for (const item of line.items) sourceItems.add(item);
|
|
116
|
+
return {
|
|
117
|
+
rowBoundariesDescPt: rowBoundaries.map((l) => l.position),
|
|
118
|
+
columnBoundariesAscPt: columnBoundaries.map((l) => l.position),
|
|
119
|
+
sourceItems
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const OUTER_EDGE_TOLERANCE_PT = 3;
|
|
123
|
+
function findRowIndex(rowBoundariesDescPt, yPt) {
|
|
124
|
+
const lastIndex = rowBoundariesDescPt.length - 1;
|
|
125
|
+
if (yPt > rowBoundariesDescPt[0] + OUTER_EDGE_TOLERANCE_PT || yPt < rowBoundariesDescPt[lastIndex] - OUTER_EDGE_TOLERANCE_PT) return;
|
|
126
|
+
for (let i = 0; i < lastIndex; i++) if (yPt > rowBoundariesDescPt[i + 1]) return i;
|
|
127
|
+
return lastIndex - 1;
|
|
128
|
+
}
|
|
129
|
+
function findColumnIndex(columnBoundariesAscPt, xPt) {
|
|
130
|
+
const lastIndex = columnBoundariesAscPt.length - 1;
|
|
131
|
+
if (xPt < columnBoundariesAscPt[0] - OUTER_EDGE_TOLERANCE_PT || xPt > columnBoundariesAscPt[lastIndex] + OUTER_EDGE_TOLERANCE_PT) return;
|
|
132
|
+
for (let j = 0; j < lastIndex; j++) if (xPt < columnBoundariesAscPt[j + 1]) return j;
|
|
133
|
+
return lastIndex - 1;
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
exports.detectGridLattice = detectGridLattice;
|
|
137
|
+
exports.extractLineCandidates = extractLineCandidates;
|
|
138
|
+
exports.findColumnIndex = findColumnIndex;
|
|
139
|
+
exports.findRowIndex = findRowIndex;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LayoutItem } from "document-schema.js";
|
|
2
|
+
//#region src/layout/lattice.d.ts
|
|
3
|
+
interface LineSegment {
|
|
4
|
+
readonly item: LayoutItem;
|
|
5
|
+
readonly x1Pt: number;
|
|
6
|
+
readonly y1Pt: number;
|
|
7
|
+
readonly x2Pt: number;
|
|
8
|
+
readonly y2Pt: number;
|
|
9
|
+
}
|
|
10
|
+
declare function extractLineCandidates(items: readonly LayoutItem[]): LineSegment[];
|
|
11
|
+
interface GridLattice {
|
|
12
|
+
readonly rowBoundariesDescPt: readonly number[];
|
|
13
|
+
readonly columnBoundariesAscPt: readonly number[];
|
|
14
|
+
readonly sourceItems: ReadonlySet<LayoutItem>;
|
|
15
|
+
}
|
|
16
|
+
declare function detectGridLattice(items: readonly LayoutItem[]): GridLattice | undefined;
|
|
17
|
+
declare function findRowIndex(rowBoundariesDescPt: readonly number[], yPt: number): number | undefined;
|
|
18
|
+
declare function findColumnIndex(columnBoundariesAscPt: readonly number[], xPt: number): number | undefined;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { GridLattice, LineSegment, detectGridLattice, extractLineCandidates, findColumnIndex, findRowIndex };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LayoutItem } from "document-schema.js";
|
|
2
|
+
//#region src/layout/lattice.d.ts
|
|
3
|
+
interface LineSegment {
|
|
4
|
+
readonly item: LayoutItem;
|
|
5
|
+
readonly x1Pt: number;
|
|
6
|
+
readonly y1Pt: number;
|
|
7
|
+
readonly x2Pt: number;
|
|
8
|
+
readonly y2Pt: number;
|
|
9
|
+
}
|
|
10
|
+
declare function extractLineCandidates(items: readonly LayoutItem[]): LineSegment[];
|
|
11
|
+
interface GridLattice {
|
|
12
|
+
readonly rowBoundariesDescPt: readonly number[];
|
|
13
|
+
readonly columnBoundariesAscPt: readonly number[];
|
|
14
|
+
readonly sourceItems: ReadonlySet<LayoutItem>;
|
|
15
|
+
}
|
|
16
|
+
declare function detectGridLattice(items: readonly LayoutItem[]): GridLattice | undefined;
|
|
17
|
+
declare function findRowIndex(rowBoundariesDescPt: readonly number[], yPt: number): number | undefined;
|
|
18
|
+
declare function findColumnIndex(columnBoundariesAscPt: readonly number[], xPt: number): number | undefined;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { GridLattice, LineSegment, detectGridLattice, extractLineCandidates, findColumnIndex, findRowIndex };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
//#region src/layout/lattice.ts
|
|
2
|
+
function extractLineCandidates(items) {
|
|
3
|
+
const segments = [];
|
|
4
|
+
for (const item of items) {
|
|
5
|
+
if (item.kind === "line") {
|
|
6
|
+
segments.push({
|
|
7
|
+
item,
|
|
8
|
+
x1Pt: item.x1Pt,
|
|
9
|
+
y1Pt: item.y1Pt,
|
|
10
|
+
x2Pt: item.x2Pt,
|
|
11
|
+
y2Pt: item.y2Pt
|
|
12
|
+
});
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (item.kind === "path" && item.stroke !== void 0 && item.subpaths.length === 1) {
|
|
16
|
+
const subpath = item.subpaths[0];
|
|
17
|
+
if (subpath.segments.length === 1 && subpath.segments[0].kind === "line") {
|
|
18
|
+
const segment = subpath.segments[0];
|
|
19
|
+
segments.push({
|
|
20
|
+
item,
|
|
21
|
+
x1Pt: subpath.startXPt,
|
|
22
|
+
y1Pt: subpath.startYPt,
|
|
23
|
+
x2Pt: segment.xPt,
|
|
24
|
+
y2Pt: segment.yPt
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return segments;
|
|
30
|
+
}
|
|
31
|
+
const AXIS_ALIGNMENT_TOLERANCE_PT = .5;
|
|
32
|
+
const MIN_GRIDLINE_LENGTH_PT = 4;
|
|
33
|
+
function classifyAxisLine(seg) {
|
|
34
|
+
const dx = Math.abs(seg.x2Pt - seg.x1Pt);
|
|
35
|
+
const dy = Math.abs(seg.y2Pt - seg.y1Pt);
|
|
36
|
+
if (dy <= AXIS_ALIGNMENT_TOLERANCE_PT && dx >= MIN_GRIDLINE_LENGTH_PT) return {
|
|
37
|
+
axis: "horizontal",
|
|
38
|
+
position: (seg.y1Pt + seg.y2Pt) / 2,
|
|
39
|
+
startPt: Math.min(seg.x1Pt, seg.x2Pt),
|
|
40
|
+
endPt: Math.max(seg.x1Pt, seg.x2Pt),
|
|
41
|
+
item: seg.item
|
|
42
|
+
};
|
|
43
|
+
if (dx <= AXIS_ALIGNMENT_TOLERANCE_PT && dy >= MIN_GRIDLINE_LENGTH_PT) return {
|
|
44
|
+
axis: "vertical",
|
|
45
|
+
position: (seg.x1Pt + seg.x2Pt) / 2,
|
|
46
|
+
startPt: Math.min(seg.y1Pt, seg.y2Pt),
|
|
47
|
+
endPt: Math.max(seg.y1Pt, seg.y2Pt),
|
|
48
|
+
item: seg.item
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const POSITION_DEDUPE_TOLERANCE_PT = .5;
|
|
52
|
+
function longestContiguousSpan(segments) {
|
|
53
|
+
const sorted = [...segments].sort((a, b) => a.startPt - b.startPt);
|
|
54
|
+
let bestStart = sorted[0].startPt;
|
|
55
|
+
let bestEnd = sorted[0].endPt;
|
|
56
|
+
let runStart = sorted[0].startPt;
|
|
57
|
+
let runEnd = sorted[0].endPt;
|
|
58
|
+
for (const segment of sorted.slice(1)) {
|
|
59
|
+
if (segment.startPt <= runEnd + POSITION_DEDUPE_TOLERANCE_PT) runEnd = Math.max(runEnd, segment.endPt);
|
|
60
|
+
else {
|
|
61
|
+
runStart = segment.startPt;
|
|
62
|
+
runEnd = segment.endPt;
|
|
63
|
+
}
|
|
64
|
+
if (runEnd - runStart > bestEnd - bestStart) {
|
|
65
|
+
bestStart = runStart;
|
|
66
|
+
bestEnd = runEnd;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
spanPt: bestEnd - bestStart,
|
|
71
|
+
startPt: bestStart,
|
|
72
|
+
endPt: bestEnd
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function dedupeAxisLines(segments, descending) {
|
|
76
|
+
const sorted = [...segments].sort((a, b) => descending ? b.position - a.position : a.position - b.position);
|
|
77
|
+
const groups = [];
|
|
78
|
+
for (const candidate of sorted) {
|
|
79
|
+
const last = groups[groups.length - 1];
|
|
80
|
+
if (last !== void 0 && Math.abs(candidate.position - last[0].position) <= POSITION_DEDUPE_TOLERANCE_PT) last.push(candidate);
|
|
81
|
+
else groups.push([candidate]);
|
|
82
|
+
}
|
|
83
|
+
return groups.map((group) => {
|
|
84
|
+
const { spanPt, startPt, endPt } = longestContiguousSpan(group);
|
|
85
|
+
return {
|
|
86
|
+
position: group[0].position,
|
|
87
|
+
spanPt,
|
|
88
|
+
startPt,
|
|
89
|
+
endPt,
|
|
90
|
+
items: group.map((segment) => segment.item)
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const MIN_GRIDLINE_COUNT_PER_AXIS = 3;
|
|
95
|
+
const GRID_SPAN_CONSISTENCY_RATIO = .9;
|
|
96
|
+
function consistentLines(lines) {
|
|
97
|
+
if (lines.length < MIN_GRIDLINE_COUNT_PER_AXIS) return [];
|
|
98
|
+
const maxSpanPt = Math.max(...lines.map((l) => l.spanPt));
|
|
99
|
+
const consistent = lines.filter((l) => l.spanPt >= maxSpanPt * GRID_SPAN_CONSISTENCY_RATIO);
|
|
100
|
+
return consistent.length >= MIN_GRIDLINE_COUNT_PER_AXIS ? consistent : [];
|
|
101
|
+
}
|
|
102
|
+
function detectGridLattice(items) {
|
|
103
|
+
const horizontal = [];
|
|
104
|
+
const vertical = [];
|
|
105
|
+
for (const seg of extractLineCandidates(items)) {
|
|
106
|
+
const classified = classifyAxisLine(seg);
|
|
107
|
+
if (classified === void 0) continue;
|
|
108
|
+
(classified.axis === "horizontal" ? horizontal : vertical).push(classified);
|
|
109
|
+
}
|
|
110
|
+
const rowBoundaries = consistentLines(dedupeAxisLines(horizontal, true));
|
|
111
|
+
const columnBoundaries = consistentLines(dedupeAxisLines(vertical, false));
|
|
112
|
+
if (rowBoundaries.length === 0 || columnBoundaries.length === 0) return;
|
|
113
|
+
const sourceItems = /* @__PURE__ */ new Set();
|
|
114
|
+
for (const line of [...rowBoundaries, ...columnBoundaries]) for (const item of line.items) sourceItems.add(item);
|
|
115
|
+
return {
|
|
116
|
+
rowBoundariesDescPt: rowBoundaries.map((l) => l.position),
|
|
117
|
+
columnBoundariesAscPt: columnBoundaries.map((l) => l.position),
|
|
118
|
+
sourceItems
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const OUTER_EDGE_TOLERANCE_PT = 3;
|
|
122
|
+
function findRowIndex(rowBoundariesDescPt, yPt) {
|
|
123
|
+
const lastIndex = rowBoundariesDescPt.length - 1;
|
|
124
|
+
if (yPt > rowBoundariesDescPt[0] + OUTER_EDGE_TOLERANCE_PT || yPt < rowBoundariesDescPt[lastIndex] - OUTER_EDGE_TOLERANCE_PT) return;
|
|
125
|
+
for (let i = 0; i < lastIndex; i++) if (yPt > rowBoundariesDescPt[i + 1]) return i;
|
|
126
|
+
return lastIndex - 1;
|
|
127
|
+
}
|
|
128
|
+
function findColumnIndex(columnBoundariesAscPt, xPt) {
|
|
129
|
+
const lastIndex = columnBoundariesAscPt.length - 1;
|
|
130
|
+
if (xPt < columnBoundariesAscPt[0] - OUTER_EDGE_TOLERANCE_PT || xPt > columnBoundariesAscPt[lastIndex] + OUTER_EDGE_TOLERANCE_PT) return;
|
|
131
|
+
for (let j = 0; j < lastIndex; j++) if (xPt < columnBoundariesAscPt[j + 1]) return j;
|
|
132
|
+
return lastIndex - 1;
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { detectGridLattice, extractLineCandidates, findColumnIndex, findRowIndex };
|