reamkit 1.33.2 → 1.34.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 +13 -10
- package/dist/esm/core/converter/facade.js +1 -0
- package/dist/esm/core/converter/ream.d.ts +6 -6
- package/dist/esm/core/converter/ream.js +11 -5
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +15 -0
- package/dist/esm/core/drawingml/text-warp.d.ts +34 -0
- package/dist/esm/core/drawingml/text-warp.js +49 -1
- package/dist/esm/core/font/index.d.ts +1 -1
- package/dist/esm/core/font/index.js +8 -0
- package/dist/esm/core/font/indic-shaper.d.ts +47 -0
- package/dist/esm/core/font/indic-shaper.js +1146 -0
- package/dist/esm/core/font/indic-table.d.ts +12 -0
- package/dist/esm/core/font/indic-table.js +463 -0
- package/dist/esm/core/font/measure.d.ts +45 -4
- package/dist/esm/core/font/measure.js +253 -14
- package/dist/esm/core/font/opentype-lookups.d.ts +214 -0
- package/dist/esm/core/font/opentype-lookups.js +1112 -0
- package/dist/esm/core/fonts/families.d.ts +4 -0
- package/dist/esm/core/fonts/families.js +43 -12
- package/dist/esm/core/fonts/provider.js +1 -0
- package/dist/esm/core/fonts/remote-fonts.d.ts +4 -2
- package/dist/esm/core/fonts/remote-fonts.js +36 -0
- package/dist/esm/core/fonts/scripts.d.ts +19 -0
- package/dist/esm/core/fonts/scripts.js +96 -1
- package/dist/esm/core/numbering/apply.js +12 -8
- package/dist/esm/core/style-cascade/index.d.ts +1 -1
- package/dist/esm/core/style-cascade/index.js +2 -2
- package/dist/esm/core/style-cascade/resolver.d.ts +9 -0
- package/dist/esm/core/style-cascade/resolver.js +31 -3
- package/dist/esm/core/style-cascade/table.js +3 -8
- package/dist/esm/excel/xlsx-to-pdf.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/layout/line-paint.d.ts +5 -4
- package/dist/esm/layout/line-paint.js +6 -5
- package/dist/esm/layout/page-doc.d.ts +26 -0
- package/dist/esm/layout/styled-layout.d.ts +8 -1
- package/dist/esm/layout/styled-layout.js +459 -112
- package/dist/esm/layout/undrawn.d.ts +18 -0
- package/dist/esm/layout/undrawn.js +59 -0
- package/dist/esm/pdf/cid-font.d.ts +5 -0
- package/dist/esm/pdf/cid-font.js +8 -2
- package/dist/esm/pdf/styled-page-emitter.js +117 -28
- package/dist/esm/pdf/text-page-renderer.js +1 -0
- package/dist/esm/pdf-reader/content.d.ts +1 -1
- package/dist/esm/pdf-reader/content.js +48 -13
- package/dist/esm/pdf-reader/embedded-fonts.js +1 -0
- package/dist/esm/pdf-reader/encodings.d.ts +9 -0
- package/dist/esm/pdf-reader/encodings.js +66 -1
- package/dist/esm/pdf-reader/face-outlines.js +1 -0
- package/dist/esm/pdf-reader/text.d.ts +10 -0
- package/dist/esm/pdf-reader/text.js +25 -3
- package/dist/esm/pdf-reader/vector.js +2 -2
- package/dist/esm/pptx/embedded-fonts.js +1 -0
- package/dist/esm/pptx/sp-helpers.js +4 -1
- package/dist/esm/svg/svg-text.js +30 -7
- package/dist/esm/word/doc/doc-reader.js +148 -57
- package/dist/esm/word/doc/doc-text.d.ts +80 -11
- package/dist/esm/word/doc/doc-text.js +438 -75
- package/dist/esm/word/document-parser.js +48 -28
- package/dist/esm/word/docx-to-pdf.d.ts +5 -5
- package/dist/esm/word/docx-to-pdf.js +9 -7
- package/dist/esm/word/docx-writer.js +3 -5
- package/dist/esm/word/font-embed.js +1 -0
- package/dist/esm/word/font-table.js +1 -0
- package/dist/esm/word/numbering-parser.js +3 -0
- package/dist/esm/word/paragraph-properties.js +2 -2
- package/dist/esm/word/run-properties.js +2 -2
- package/dist/esm/word/xml-helpers.d.ts +18 -0
- package/dist/esm/word/xml-helpers.js +48 -1
- package/package.json +2 -2
|
@@ -4,6 +4,10 @@ import { FlowDoc } from '../ir/flow.js';
|
|
|
4
4
|
* The curated substitute families a document's text needs, always including the
|
|
5
5
|
* sans default as the fallback for unstyled runs, math and chart labels.
|
|
6
6
|
*
|
|
7
|
+
* §17.3.2.26 — a run names a family per slot, and the text decides which slots
|
|
8
|
+
* are drawn from (see {@link fontSlotOf}): the hAnsi family of a document all
|
|
9
|
+
* in ASCII is never asked for, and is not fetched.
|
|
10
|
+
*
|
|
7
11
|
* @param flow The parsed document.
|
|
8
12
|
* @returns One {@link FamilyKey} per distinct family the document names.
|
|
9
13
|
*/
|
|
@@ -1,33 +1,64 @@
|
|
|
1
1
|
import { resolveFamilyKey } from "./remote-fonts.js";
|
|
2
|
+
import { fontSlotOf } from "./scripts.js";
|
|
2
3
|
//#region src/core/fonts/families.ts
|
|
4
|
+
var SLOTS = [
|
|
5
|
+
"ascii",
|
|
6
|
+
"hAnsi",
|
|
7
|
+
"eastAsia",
|
|
8
|
+
"cs"
|
|
9
|
+
];
|
|
3
10
|
/**
|
|
4
11
|
* The curated substitute families a document's text needs, always including the
|
|
5
12
|
* sans default as the fallback for unstyled runs, math and chart labels.
|
|
6
13
|
*
|
|
14
|
+
* §17.3.2.26 — a run names a family per slot, and the text decides which slots
|
|
15
|
+
* are drawn from (see {@link fontSlotOf}): the hAnsi family of a document all
|
|
16
|
+
* in ASCII is never asked for, and is not fetched.
|
|
17
|
+
*
|
|
7
18
|
* @param flow The parsed document.
|
|
8
19
|
* @returns One {@link FamilyKey} per distinct family the document names.
|
|
9
20
|
*/
|
|
10
21
|
function familiesInFlow(flow) {
|
|
11
|
-
const names =
|
|
12
|
-
|
|
13
|
-
|
|
22
|
+
const names = {
|
|
23
|
+
ascii: /* @__PURE__ */ new Set(),
|
|
24
|
+
hAnsi: /* @__PURE__ */ new Set(),
|
|
25
|
+
eastAsia: /* @__PURE__ */ new Set(),
|
|
26
|
+
cs: /* @__PURE__ */ new Set()
|
|
27
|
+
};
|
|
28
|
+
const used = /* @__PURE__ */ new Set(["ascii"]);
|
|
29
|
+
const add = (props) => {
|
|
30
|
+
for (const slot of SLOTS) {
|
|
31
|
+
const name = props?.fontFamily?.[slot];
|
|
32
|
+
if (name !== void 0 && name.trim() !== "") names[slot].add(name.trim().toLowerCase());
|
|
33
|
+
}
|
|
34
|
+
if (props?.rtl === true) used.add("cs");
|
|
35
|
+
};
|
|
36
|
+
const read = (text) => {
|
|
37
|
+
for (const ch of text) {
|
|
38
|
+
if (used.size === SLOTS.length) return;
|
|
39
|
+
const cp = ch.codePointAt(0) ?? 0;
|
|
40
|
+
if (cp > 127) used.add(fontSlotOf(cp));
|
|
41
|
+
}
|
|
14
42
|
};
|
|
15
|
-
add(flow.styles.defaultRunProperties
|
|
43
|
+
add(flow.styles.defaultRunProperties);
|
|
16
44
|
for (const style of flow.styles.styles.values()) {
|
|
17
|
-
add(style.runProperties
|
|
18
|
-
add(style.paragraphProperties.runProperties
|
|
19
|
-
add(style.tableLayer?.runProperties
|
|
20
|
-
for (const c of style.tableConditions ?? []) add(c.layer.runProperties
|
|
45
|
+
add(style.runProperties);
|
|
46
|
+
add(style.paragraphProperties.runProperties);
|
|
47
|
+
add(style.tableLayer?.runProperties);
|
|
48
|
+
for (const c of style.tableConditions ?? []) add(c.layer.runProperties);
|
|
21
49
|
}
|
|
22
|
-
for (const abstract of flow.numbering?.abstractNums.values() ?? []) for (const level of abstract.levels.values()) add(level.runProperties
|
|
50
|
+
for (const abstract of flow.numbering?.abstractNums.values() ?? []) for (const level of abstract.levels.values()) add(level.runProperties);
|
|
23
51
|
const shapeText = (shape) => {
|
|
24
52
|
if (shape.text) visit(shape.text.content);
|
|
25
53
|
for (const child of shape.children ?? []) shapeText(child.shape);
|
|
26
54
|
};
|
|
27
55
|
const visit = (elements) => {
|
|
28
56
|
for (const el of elements) if (el.kind === "paragraph") {
|
|
29
|
-
add(el.paragraph.properties.runProperties
|
|
30
|
-
for (const run of el.paragraph.runs)
|
|
57
|
+
add(el.paragraph.properties.runProperties);
|
|
58
|
+
for (const run of el.paragraph.runs) {
|
|
59
|
+
add(run.properties);
|
|
60
|
+
read(run.text);
|
|
61
|
+
}
|
|
31
62
|
} else if (el.kind === "table") {
|
|
32
63
|
for (const row of el.table.rows) for (const cell of row.cells) visit(cell.content);
|
|
33
64
|
visit(el.table.overlay?.drawings ?? []);
|
|
@@ -39,7 +70,7 @@ function familiesInFlow(flow) {
|
|
|
39
70
|
for (const note of flow.endnotes?.values() ?? []) visit(note);
|
|
40
71
|
for (const comment of flow.comments?.values() ?? []) visit(comment.content);
|
|
41
72
|
const keys = /* @__PURE__ */ new Set(["arimo"]);
|
|
42
|
-
for (const name of names) keys.add(resolveFamilyKey(name));
|
|
73
|
+
for (const slot of used) for (const name of names[slot]) keys.add(resolveFamilyKey(name));
|
|
43
74
|
return keys;
|
|
44
75
|
}
|
|
45
76
|
//#endregion
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { fetchFontSet, resolveFamilyKey } from "./remote-fonts.js";
|
|
2
2
|
import { pickVariant } from "../font/font-registry.js";
|
|
3
|
+
import "../font/index.js";
|
|
3
4
|
//#region src/core/fonts/provider.ts
|
|
4
5
|
/** The shared `none` answer — a provider that cannot satisfy a request. */
|
|
5
6
|
var NO_FONT = { kind: "none" };
|
|
@@ -5,13 +5,15 @@ export type FamilyKey = 'arimo' | 'tinos' | 'cousine' | 'carlito' | 'caladea';
|
|
|
5
5
|
* A WRITING SYSTEM the curated five cannot draw at all. They are Latin families
|
|
6
6
|
* — Greek, Cyrillic and Hebrew ride along, everything else is a notdef box —
|
|
7
7
|
* and 2145 characters of the corpus fall outside them: Han, Kana, Hangul,
|
|
8
|
-
* Arabic, the geometric symbols a form's checkbox is made of.
|
|
8
|
+
* Arabic, the geometric symbols a form's checkbox is made of. The scripts of
|
|
9
|
+
* India are outside them too, and a line of Hindi, Tamil or Bengali came out
|
|
10
|
+
* as a row of boxes.
|
|
9
11
|
*
|
|
10
12
|
* These are fetched only when a document actually holds such a character, and
|
|
11
13
|
* only in the regular weight: Noto Sans SC is ten megabytes, and a bold run in
|
|
12
14
|
* it is better stroked (see `SyntheticFace`) than downloaded four times over.
|
|
13
15
|
*/
|
|
14
|
-
export type ScriptKey = 'jp' | 'kr' | 'sc' | 'arabic' | 'hebrew' | 'thai' | 'symbols1' | 'symbols2';
|
|
16
|
+
export type ScriptKey = 'jp' | 'kr' | 'sc' | 'arabic' | 'hebrew' | 'thai' | 'devanagari' | 'bengali' | 'gurmukhi' | 'gujarati' | 'oriya' | 'tamil' | 'telugu' | 'kannada' | 'malayalam' | 'symbols1' | 'symbols2';
|
|
15
17
|
/** Either kind of substitute — a Latin family or a per-script face. */
|
|
16
18
|
export type SubstituteKey = FamilyKey | ScriptKey;
|
|
17
19
|
/** Whether a substitute key names a writing system rather than a Latin family. */
|
|
@@ -31,6 +31,42 @@ var SCRIPTS = {
|
|
|
31
31
|
pkg: "noto-sans-thai",
|
|
32
32
|
file: "NotoSansThai"
|
|
33
33
|
},
|
|
34
|
+
devanagari: {
|
|
35
|
+
pkg: "noto-sans-devanagari",
|
|
36
|
+
file: "NotoSansDevanagari"
|
|
37
|
+
},
|
|
38
|
+
bengali: {
|
|
39
|
+
pkg: "noto-sans-bengali",
|
|
40
|
+
file: "NotoSansBengali"
|
|
41
|
+
},
|
|
42
|
+
gurmukhi: {
|
|
43
|
+
pkg: "noto-sans-gurmukhi",
|
|
44
|
+
file: "NotoSansGurmukhi"
|
|
45
|
+
},
|
|
46
|
+
gujarati: {
|
|
47
|
+
pkg: "noto-sans-gujarati",
|
|
48
|
+
file: "NotoSansGujarati"
|
|
49
|
+
},
|
|
50
|
+
oriya: {
|
|
51
|
+
pkg: "noto-sans-oriya",
|
|
52
|
+
file: "NotoSansOriya"
|
|
53
|
+
},
|
|
54
|
+
tamil: {
|
|
55
|
+
pkg: "noto-sans-tamil",
|
|
56
|
+
file: "NotoSansTamil"
|
|
57
|
+
},
|
|
58
|
+
telugu: {
|
|
59
|
+
pkg: "noto-sans-telugu",
|
|
60
|
+
file: "NotoSansTelugu"
|
|
61
|
+
},
|
|
62
|
+
kannada: {
|
|
63
|
+
pkg: "noto-sans-kannada",
|
|
64
|
+
file: "NotoSansKannada"
|
|
65
|
+
},
|
|
66
|
+
malayalam: {
|
|
67
|
+
pkg: "noto-sans-malayalam",
|
|
68
|
+
file: "NotoSansMalayalam"
|
|
69
|
+
},
|
|
34
70
|
symbols1: {
|
|
35
71
|
pkg: "noto-sans-symbols",
|
|
36
72
|
file: "NotoSansSymbols"
|
|
@@ -9,6 +9,25 @@ import { ScriptKey } from './remote-fonts.js';
|
|
|
9
9
|
* {@link scriptsInFlow}); defaults to Simplified.
|
|
10
10
|
*/
|
|
11
11
|
export declare function scriptForCodepoint(cp: number, hanFace?: ScriptKey): ScriptKey | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* §17.3.2.26 — the slot of `w:rFonts` a character is set in: `ascii`,
|
|
14
|
+
* `hAnsi` (high ANSI), `eastAsia` or `cs` (complex script).
|
|
15
|
+
*/
|
|
16
|
+
export type FontSlot = 'ascii' | 'hAnsi' | 'eastAsia' | 'cs';
|
|
17
|
+
/**
|
|
18
|
+
* §17.3.2.26 — the slot of a run's fonts Word sets a character in: ASCII in
|
|
19
|
+
* `ascii`, East Asian text in `eastAsia`, complex script in `cs`, and the rest
|
|
20
|
+
* above ASCII — Cyrillic, Greek, accented Latin, curly quotes — in `hAnsi`. A
|
|
21
|
+
* `w:rtl` run is complex script whole (§17.3.2.30), its digits and Latin too.
|
|
22
|
+
*
|
|
23
|
+
* Measured in Word for Mac on a run whose ascii font is Verdana and whose
|
|
24
|
+
* hAnsi one is Courier New: "split" reports Verdana, "Кириллица" Courier New.
|
|
25
|
+
*
|
|
26
|
+
* @param cp The code point.
|
|
27
|
+
* @param rtl Whether the run is right-to-left.
|
|
28
|
+
* @returns The slot.
|
|
29
|
+
*/
|
|
30
|
+
export declare function fontSlotOf(cp: number, rtl?: boolean): FontSlot;
|
|
12
31
|
/**
|
|
13
32
|
* The writing systems a document holds text in, beside the Latin one.
|
|
14
33
|
*
|
|
@@ -20,6 +20,56 @@ var RANGES = [
|
|
|
20
20
|
2303,
|
|
21
21
|
"arabic"
|
|
22
22
|
],
|
|
23
|
+
[
|
|
24
|
+
2304,
|
|
25
|
+
2403,
|
|
26
|
+
"devanagari"
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
2406,
|
|
30
|
+
2431,
|
|
31
|
+
"devanagari"
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
2432,
|
|
35
|
+
2559,
|
|
36
|
+
"bengali"
|
|
37
|
+
],
|
|
38
|
+
[
|
|
39
|
+
2560,
|
|
40
|
+
2687,
|
|
41
|
+
"gurmukhi"
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
2688,
|
|
45
|
+
2815,
|
|
46
|
+
"gujarati"
|
|
47
|
+
],
|
|
48
|
+
[
|
|
49
|
+
2816,
|
|
50
|
+
2943,
|
|
51
|
+
"oriya"
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
2944,
|
|
55
|
+
3071,
|
|
56
|
+
"tamil"
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
3072,
|
|
60
|
+
3199,
|
|
61
|
+
"telugu"
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
3200,
|
|
65
|
+
3327,
|
|
66
|
+
"kannada"
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
3328,
|
|
70
|
+
3455,
|
|
71
|
+
"malayalam"
|
|
72
|
+
],
|
|
23
73
|
[
|
|
24
74
|
3584,
|
|
25
75
|
3711,
|
|
@@ -30,6 +80,11 @@ var RANGES = [
|
|
|
30
80
|
4607,
|
|
31
81
|
"kr"
|
|
32
82
|
],
|
|
83
|
+
[
|
|
84
|
+
7376,
|
|
85
|
+
7423,
|
|
86
|
+
"devanagari"
|
|
87
|
+
],
|
|
33
88
|
[
|
|
34
89
|
8592,
|
|
35
90
|
8703,
|
|
@@ -80,6 +135,11 @@ var RANGES = [
|
|
|
80
135
|
40959,
|
|
81
136
|
"han"
|
|
82
137
|
],
|
|
138
|
+
[
|
|
139
|
+
43232,
|
|
140
|
+
43263,
|
|
141
|
+
"devanagari"
|
|
142
|
+
],
|
|
83
143
|
[
|
|
84
144
|
44032,
|
|
85
145
|
55215,
|
|
@@ -125,6 +185,41 @@ function scriptForCodepoint(cp, hanFace = "sc") {
|
|
|
125
185
|
if (cp <= hi) return key === "han" ? hanFace : key;
|
|
126
186
|
}
|
|
127
187
|
}
|
|
188
|
+
/** The scripts Word sets in a run's complex-script font, `w:cs`. */
|
|
189
|
+
var COMPLEX_SCRIPTS = /* @__PURE__ */ new Set([
|
|
190
|
+
"hebrew",
|
|
191
|
+
"arabic",
|
|
192
|
+
"thai",
|
|
193
|
+
"devanagari",
|
|
194
|
+
"bengali",
|
|
195
|
+
"gurmukhi",
|
|
196
|
+
"gujarati",
|
|
197
|
+
"oriya",
|
|
198
|
+
"tamil",
|
|
199
|
+
"telugu",
|
|
200
|
+
"kannada",
|
|
201
|
+
"malayalam"
|
|
202
|
+
]);
|
|
203
|
+
/**
|
|
204
|
+
* §17.3.2.26 — the slot of a run's fonts Word sets a character in: ASCII in
|
|
205
|
+
* `ascii`, East Asian text in `eastAsia`, complex script in `cs`, and the rest
|
|
206
|
+
* above ASCII — Cyrillic, Greek, accented Latin, curly quotes — in `hAnsi`. A
|
|
207
|
+
* `w:rtl` run is complex script whole (§17.3.2.30), its digits and Latin too.
|
|
208
|
+
*
|
|
209
|
+
* Measured in Word for Mac on a run whose ascii font is Verdana and whose
|
|
210
|
+
* hAnsi one is Courier New: "split" reports Verdana, "Кириллица" Courier New.
|
|
211
|
+
*
|
|
212
|
+
* @param cp The code point.
|
|
213
|
+
* @param rtl Whether the run is right-to-left.
|
|
214
|
+
* @returns The slot.
|
|
215
|
+
*/
|
|
216
|
+
function fontSlotOf(cp, rtl = false) {
|
|
217
|
+
if (rtl) return "cs";
|
|
218
|
+
if (cp <= 127) return "ascii";
|
|
219
|
+
const script = scriptForCodepoint(cp);
|
|
220
|
+
if (script !== void 0 && COMPLEX_SCRIPTS.has(script)) return "cs";
|
|
221
|
+
return script === "kr" || script === "jp" || script === "sc" ? "eastAsia" : "hAnsi";
|
|
222
|
+
}
|
|
128
223
|
/**
|
|
129
224
|
* The writing systems a document holds text in, beside the Latin one.
|
|
130
225
|
*
|
|
@@ -181,4 +276,4 @@ function scriptsInFlow(flow) {
|
|
|
181
276
|
};
|
|
182
277
|
}
|
|
183
278
|
//#endregion
|
|
184
|
-
export { scriptForCodepoint, scriptsInFlow };
|
|
279
|
+
export { fontSlotOf, scriptForCodepoint, scriptsInFlow };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pt } from "../ir/units.js";
|
|
2
2
|
import { NumberingState, effectiveAbstract } from "./state.js";
|
|
3
|
-
import { resolveParagraphProperties } from "../style-cascade/resolver.js";
|
|
3
|
+
import { mergeRunPartial, resolveParagraphProperties } from "../style-cascade/resolver.js";
|
|
4
4
|
import "../style-cascade/index.js";
|
|
5
5
|
//#region src/core/numbering/apply.ts
|
|
6
6
|
/** The height a picture bullet takes when neither the level nor the paragraph
|
|
@@ -36,6 +36,7 @@ function applyNumbering(body, numbering, styles) {
|
|
|
36
36
|
const pic = level?.picBullet;
|
|
37
37
|
const bulletCapPt = level?.runProperties.fontSizePt ?? p.properties.runProperties?.fontSizePt ?? DEFAULT_BULLET_HEIGHT_PT;
|
|
38
38
|
const bulletScale = pic ? Math.min(1, bulletCapPt / Math.max(1, pic.heightPt)) : 1;
|
|
39
|
+
const suffix = level?.suffix ?? "tab";
|
|
39
40
|
const markerRuns = pic ? [{
|
|
40
41
|
text: "",
|
|
41
42
|
properties: {},
|
|
@@ -45,18 +46,21 @@ function applyNumbering(body, numbering, styles) {
|
|
|
45
46
|
width: pt(pic.widthPt * bulletScale),
|
|
46
47
|
height: pt(pic.heightPt * bulletScale)
|
|
47
48
|
}
|
|
48
|
-
}, {
|
|
49
|
+
}, ...suffix === "tab" ? [{
|
|
49
50
|
text: " ",
|
|
50
51
|
properties: {},
|
|
51
52
|
listMarker: true
|
|
52
|
-
}] : [{
|
|
53
|
-
text: `${marker.replaceAll(SOFT_HYPHEN, "-")}
|
|
54
|
-
properties: {
|
|
55
|
-
...p.properties.runProperties,
|
|
56
|
-
...level?.runProperties
|
|
57
|
-
},
|
|
53
|
+
}] : []] : [{
|
|
54
|
+
text: `${marker.replaceAll(SOFT_HYPHEN, "-")}${suffix === "tab" ? " " : ""}`,
|
|
55
|
+
properties: mergeRunPartial(p.properties.runProperties ?? {}, level?.runProperties ?? {}),
|
|
58
56
|
listMarker: true
|
|
59
57
|
}];
|
|
58
|
+
if (suffix === "space") markerRuns.push({
|
|
59
|
+
text: " ",
|
|
60
|
+
properties: markerRuns[0].properties,
|
|
61
|
+
listMarker: true,
|
|
62
|
+
listMarkerSpace: true
|
|
63
|
+
});
|
|
60
64
|
const newProps = mergeIndentFromLevel(p.properties, level?.paragraphProperties);
|
|
61
65
|
return {
|
|
62
66
|
...p,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { EMPTY_STYLE_SHEET, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties, } from './resolver.js';
|
|
1
|
+
export { EMPTY_STYLE_SHEET, mergeRunPartial, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties, } from './resolver.js';
|
|
2
2
|
export type { ResolvedRunProperties, ResolvedParagraphProperties, } from './types.js';
|
|
3
3
|
export { DEFAULT_RESOLVED_RUN, DEFAULT_RESOLVED_PARAGRAPH } from './types.js';
|
|
4
4
|
export { resolveTableStyles } from './table.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { DEFAULT_RESOLVED_PARAGRAPH, DEFAULT_RESOLVED_RUN } from "./types.js";
|
|
2
|
-
import { EMPTY_STYLE_SHEET, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties } from "./resolver.js";
|
|
2
|
+
import { EMPTY_STYLE_SHEET, mergeRunPartial, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties } from "./resolver.js";
|
|
3
3
|
import { resolveTableStyles } from "./table.js";
|
|
4
|
-
export { DEFAULT_RESOLVED_PARAGRAPH, DEFAULT_RESOLVED_RUN, EMPTY_STYLE_SHEET, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties, resolveTableStyles };
|
|
4
|
+
export { DEFAULT_RESOLVED_PARAGRAPH, DEFAULT_RESOLVED_RUN, EMPTY_STYLE_SHEET, mergeRunPartial, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties, resolveTableStyles };
|
|
@@ -24,6 +24,15 @@ export declare function resolveRunProperties(runDirect: RunProperties, paragraph
|
|
|
24
24
|
* @param sheet The stylesheet supplying defaults and style chains.
|
|
25
25
|
*/
|
|
26
26
|
export declare function resolveParagraphProperties(paragraphDirect: ParagraphProperties, sheet: StyleSheet): ResolvedParagraphProperties;
|
|
27
|
+
/**
|
|
28
|
+
* Lay one layer of run properties over another (§17.7.2): each property the
|
|
29
|
+
* higher layer states wins, and each slot of its `w:rFonts` on its own.
|
|
30
|
+
*
|
|
31
|
+
* @param base The lower layer.
|
|
32
|
+
* @param override The higher layer.
|
|
33
|
+
* @returns The two as one layer.
|
|
34
|
+
*/
|
|
35
|
+
export declare function mergeRunPartial(base: RunProperties, override: RunProperties): RunProperties;
|
|
27
36
|
/**
|
|
28
37
|
* Resolve the style cascade across an entire body so the tree carries final
|
|
29
38
|
* effective run/paragraph properties (FlowDoc transform, ir-design stage 6).
|
|
@@ -131,7 +131,7 @@ function mergeRun(base, override) {
|
|
|
131
131
|
smallCaps: override.smallCaps ?? base.smallCaps,
|
|
132
132
|
fontSizePt: override.fontSizePt ?? base.fontSizePt,
|
|
133
133
|
colorHex: override.colorHex ?? base.colorHex,
|
|
134
|
-
fontFamily:
|
|
134
|
+
fontFamily: mergeFontFamily(base.fontFamily, override.fontFamily),
|
|
135
135
|
verticalAlign: override.verticalAlign ?? base.verticalAlign,
|
|
136
136
|
rtl: override.rtl ?? base.rtl,
|
|
137
137
|
...lang !== void 0 ? { lang } : {},
|
|
@@ -185,8 +185,36 @@ function mergePar(base, override) {
|
|
|
185
185
|
...beforeAuto !== void 0 ? { spacingBeforeAuto: beforeAuto } : {}
|
|
186
186
|
};
|
|
187
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Lay one layer of run properties over another (§17.7.2): each property the
|
|
190
|
+
* higher layer states wins, and each slot of its `w:rFonts` on its own.
|
|
191
|
+
*
|
|
192
|
+
* @param base The lower layer.
|
|
193
|
+
* @param override The higher layer.
|
|
194
|
+
* @returns The two as one layer.
|
|
195
|
+
*/
|
|
188
196
|
function mergeRunPartial(base, override) {
|
|
189
|
-
|
|
197
|
+
const out = copyDefined(base, override);
|
|
198
|
+
const fontFamily = mergeFontFamily(base.fontFamily, override.fontFamily);
|
|
199
|
+
return fontFamily === void 0 || fontFamily === out.fontFamily ? out : {
|
|
200
|
+
...out,
|
|
201
|
+
fontFamily
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function mergeFontFamily(base, override) {
|
|
205
|
+
if (override === void 0) return base;
|
|
206
|
+
if (base === void 0) return override;
|
|
207
|
+
const ascii = override.ascii ?? base.ascii;
|
|
208
|
+
const hAnsi = override.hAnsi ?? base.hAnsi;
|
|
209
|
+
const eastAsia = override.eastAsia ?? base.eastAsia;
|
|
210
|
+
const cs = override.cs ?? base.cs;
|
|
211
|
+
if (ascii === override.ascii && hAnsi === override.hAnsi && eastAsia === override.eastAsia && cs === override.cs) return override;
|
|
212
|
+
return {
|
|
213
|
+
...ascii !== void 0 ? { ascii } : {},
|
|
214
|
+
...hAnsi !== void 0 ? { hAnsi } : {},
|
|
215
|
+
...eastAsia !== void 0 ? { eastAsia } : {},
|
|
216
|
+
...cs !== void 0 ? { cs } : {}
|
|
217
|
+
};
|
|
190
218
|
}
|
|
191
219
|
function mergeParPartial(base, override) {
|
|
192
220
|
const out = copyDefined(base, override);
|
|
@@ -291,4 +319,4 @@ function resolveHeadersFootersStyles(hf, sheet) {
|
|
|
291
319
|
return hf;
|
|
292
320
|
}
|
|
293
321
|
//#endregion
|
|
294
|
-
export { EMPTY_STYLE_SHEET, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties };
|
|
322
|
+
export { EMPTY_STYLE_SHEET, mergeRunPartial, resolveBodyStyles, resolveHeadersFootersStyles, resolveParagraphProperties, resolveRunProperties };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mergeRunPartial } from "./resolver.js";
|
|
1
2
|
//#region src/core/style-cascade/table.ts
|
|
2
3
|
/**
|
|
3
4
|
* Apply table styles across a body (ECMA-376 §17.7.6): for each table, fold its
|
|
@@ -88,10 +89,7 @@ function applyLayerToCell(tableCell, layer, directBorders, pos) {
|
|
|
88
89
|
};
|
|
89
90
|
if (layer.runProperties) p.properties = {
|
|
90
91
|
...p.properties,
|
|
91
|
-
inheritedRun: {
|
|
92
|
-
...p.properties.inheritedRun,
|
|
93
|
-
...layer.runProperties
|
|
94
|
-
}
|
|
92
|
+
inheritedRun: mergeRunPartial(p.properties.inheritedRun ?? {}, layer.runProperties)
|
|
95
93
|
};
|
|
96
94
|
}
|
|
97
95
|
}
|
|
@@ -170,10 +168,7 @@ function mergeLayer(base, override) {
|
|
|
170
168
|
} } : {},
|
|
171
169
|
...(override.indentPt ?? base.indentPt) !== void 0 ? { indentPt: override.indentPt ?? base.indentPt } : {},
|
|
172
170
|
...override.shading ?? base.shading ? { shading: override.shading ?? base.shading } : {},
|
|
173
|
-
...override.runProperties ?? base.runProperties ? { runProperties: {
|
|
174
|
-
...base.runProperties,
|
|
175
|
-
...definedOnly(override.runProperties ?? {})
|
|
176
|
-
} } : {},
|
|
171
|
+
...override.runProperties ?? base.runProperties ? { runProperties: mergeRunPartial(base.runProperties ?? {}, override.runProperties ?? {}) } : {},
|
|
177
172
|
...override.paragraphProperties ?? base.paragraphProperties ? { paragraphProperties: {
|
|
178
173
|
...base.paragraphProperties,
|
|
179
174
|
...definedOnly(override.paragraphProperties ?? {})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fetchFontSet } from "../core/fonts/remote-fonts.js";
|
|
2
2
|
import { FontRegistry } from "../core/font/font-registry.js";
|
|
3
3
|
import { createFontMeasure } from "../core/font/measure.js";
|
|
4
|
+
import "../core/font/index.js";
|
|
4
5
|
import { signPdf } from "../pdf/signature.js";
|
|
5
6
|
import { renderStyledPdf, renderStyledPdfEncrypted } from "../pdf/styled-page-renderer.js";
|
|
6
7
|
import "../pdf/index.js";
|
package/dist/esm/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { fetchFontSet, resolveFamilyKey } from "./core/fonts/remote-fonts.js";
|
|
|
2
2
|
import { parseTtf } from "./core/font/ttf-parser.js";
|
|
3
3
|
import { subsetTtf } from "./core/font/ttf-subset.js";
|
|
4
4
|
import { FontRegistry } from "./core/font/font-registry.js";
|
|
5
|
+
import "./core/font/index.js";
|
|
5
6
|
import { eighthPtToPt, emuToPt, halfPtToPt, inchToPt, mmToPt, pt, pxToPt, twipsToPt } from "./core/ir/units.js";
|
|
6
7
|
import { ResourceStore } from "./core/ir/resources.js";
|
|
7
8
|
import { FEATURES } from "./core/ir/features.js";
|
|
@@ -28,10 +28,11 @@ export declare function lineVisualOrder(line: Line): Array<number>;
|
|
|
28
28
|
export declare function computeJustifyExtra(line: Line): number;
|
|
29
29
|
/**
|
|
30
30
|
* Whether a line is ONE text matrix and a run of glyphs: nothing in it placed
|
|
31
|
-
* on its own — a tab, a
|
|
32
|
-
* run, a rise, a faked italic — and nothing drawn
|
|
33
|
-
* shading, a highlight or a rule. Only such a line
|
|
34
|
-
* alone; any other is placed token by token in
|
|
31
|
+
* on its own — a tab, a list marker's space, a stretched space, a picture, a
|
|
32
|
+
* formula, a right-to-left run, a rise, a faked italic — and nothing drawn
|
|
33
|
+
* beside its glyphs, a run's shading, a highlight or a rule. Only such a line
|
|
34
|
+
* can be turned by its matrix alone; any other is placed token by token in
|
|
35
|
+
* page space.
|
|
35
36
|
*
|
|
36
37
|
* @param line The laid-out line.
|
|
37
38
|
* @returns True when a single text matrix sets the whole of it.
|
|
@@ -70,16 +70,17 @@ function computeJustifyExtra(line) {
|
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
72
|
* Whether a line is ONE text matrix and a run of glyphs: nothing in it placed
|
|
73
|
-
* on its own — a tab, a
|
|
74
|
-
* run, a rise, a faked italic — and nothing drawn
|
|
75
|
-
* shading, a highlight or a rule. Only such a line
|
|
76
|
-
* alone; any other is placed token by token in
|
|
73
|
+
* on its own — a tab, a list marker's space, a stretched space, a picture, a
|
|
74
|
+
* formula, a right-to-left run, a rise, a faked italic — and nothing drawn
|
|
75
|
+
* beside its glyphs, a run's shading, a highlight or a rule. Only such a line
|
|
76
|
+
* can be turned by its matrix alone; any other is placed token by token in
|
|
77
|
+
* page space.
|
|
77
78
|
*
|
|
78
79
|
* @param line The laid-out line.
|
|
79
80
|
* @returns True when a single text matrix sets the whole of it.
|
|
80
81
|
*/
|
|
81
82
|
function settableInOneMatrix(line) {
|
|
82
|
-
return computeJustifyExtra(line) === 0 && line.tokens.every((t) => t.kind === "text" && t.tab !== true && t.bidiLevel % 2 === 0 && t.risePt === void 0 && t.synthetic?.italic !== true && t.highlight !== true && t.resolvedRun.shadingColorHex === void 0 && t.resolvedRun.underline === "none" && !t.resolvedRun.strike);
|
|
83
|
+
return computeJustifyExtra(line) === 0 && line.tokens.every((t) => t.kind === "text" && t.tab !== true && t.listMarkerSpace !== true && t.bidiLevel % 2 === 0 && t.risePt === void 0 && t.synthetic?.italic !== true && t.highlight !== true && t.resolvedRun.shadingColorHex === void 0 && t.resolvedRun.underline === "none" && !t.resolvedRun.strike);
|
|
83
84
|
}
|
|
84
85
|
/**
|
|
85
86
|
* §14.1.2.10 — the wash a picture is drawn through, as the flat veil it is.
|
|
@@ -16,6 +16,11 @@ export interface FontResource {
|
|
|
16
16
|
readonly measure: FontMeasure;
|
|
17
17
|
/** Glyphs collected by the usage walk — the emit phase subsets to these. */
|
|
18
18
|
readonly gids: ReadonlySet<number>;
|
|
19
|
+
/**
|
|
20
|
+
* The text of each collected glyph that no character maps to — a conjunct,
|
|
21
|
+
* a reph, a vowel sign's contextual form — for the PDF's /ToUnicode.
|
|
22
|
+
*/
|
|
23
|
+
readonly glyphText?: ReadonlyMap<number, string>;
|
|
19
24
|
}
|
|
20
25
|
/**
|
|
21
26
|
* The face a run asked for and the registry could not give — what the page has
|
|
@@ -60,11 +65,23 @@ export interface TextToken {
|
|
|
60
65
|
* element separate from the item body.
|
|
61
66
|
*/
|
|
62
67
|
readonly listMarker?: true;
|
|
68
|
+
/**
|
|
69
|
+
* §17.9.29 — the token is the space a list level's `w:suff="space"` puts
|
|
70
|
+
* after its marker: a gap of fixed width with nothing drawn in it, which a
|
|
71
|
+
* justified line does not stretch.
|
|
72
|
+
*/
|
|
73
|
+
readonly listMarkerSpace?: true;
|
|
63
74
|
/**
|
|
64
75
|
* §17.3.3.1 — the token is the break of a `w:br w:type="column"`: what
|
|
65
76
|
* follows it belongs in the next column.
|
|
66
77
|
*/
|
|
67
78
|
readonly columnBreak?: true;
|
|
79
|
+
/**
|
|
80
|
+
* §17.3.3.1 — the token is a `w:br w:type="page"`: an empty mark of where it
|
|
81
|
+
* stands, and what follows it belongs on the next page. Layout takes it out
|
|
82
|
+
* of the line before the line is wrapped.
|
|
83
|
+
*/
|
|
84
|
+
readonly pageBreak?: true;
|
|
68
85
|
/**
|
|
69
86
|
* §17.3.1.38 — the token IS a tab: its width is the distance to the stop it
|
|
70
87
|
* advances to, resolved once the line is known, and its text is whatever
|
|
@@ -76,6 +93,15 @@ export interface TextToken {
|
|
|
76
93
|
* fills a soft highlight behind it (E-COMMENTS CM2c).
|
|
77
94
|
*/
|
|
78
95
|
readonly highlight?: true;
|
|
96
|
+
/**
|
|
97
|
+
* Per code point of `text`, the colour it is drawn in, where the token holds
|
|
98
|
+
* a syllable of the scripts of India that a run boundary cut: the syllable
|
|
99
|
+
* is shaped whole in the run it begins in, and each character keeps the
|
|
100
|
+
* colour of the run it was typed in. A glyph standing for several characters
|
|
101
|
+
* takes the colour of the first. Absent when every character takes
|
|
102
|
+
* `resolvedRun.colorHex`.
|
|
103
|
+
*/
|
|
104
|
+
readonly charColorsHex?: ReadonlyArray<string>;
|
|
79
105
|
readonly resolvedRun: ResolvedRunProperties;
|
|
80
106
|
readonly font: FontResource;
|
|
81
107
|
/** What the chosen face lacks and the emitter must fake (see {@link SyntheticFace}). */
|
|
@@ -2,7 +2,7 @@ import { BodyElement, Chart, Comment, DocumentInfo, Numbering, Section, SectionP
|
|
|
2
2
|
import { FontRegistry } from '../core/font/index.js';
|
|
3
3
|
import { SubstituteKey } from '../core/fonts/index.js';
|
|
4
4
|
import { Hyphenator } from '../core/hyphenation/index.js';
|
|
5
|
-
import { Pt, ResourceStore } from '../core/ir/index.js';
|
|
5
|
+
import { Loss, Pt, ResourceStore } from '../core/ir/index.js';
|
|
6
6
|
import { LaidOutDocument, PageItem } from './page-doc.js';
|
|
7
7
|
import { AttachedFile } from '../pdf/embedded-file.js';
|
|
8
8
|
import { SignaturePlaceholder } from '../pdf/signature.js';
|
|
@@ -221,6 +221,13 @@ export interface StyledRenderOptions {
|
|
|
221
221
|
* signature.
|
|
222
222
|
*/
|
|
223
223
|
readonly signaturePlaceholder?: SignaturePlaceholder;
|
|
224
|
+
/**
|
|
225
|
+
* Sink the layout writes its {@link Loss} entries into: the characters no
|
|
226
|
+
* face on hand has a glyph for, which the page draws as empty boxes (see
|
|
227
|
+
* `undrawnLoss`). The converter always supplies one and returns it with the
|
|
228
|
+
* output; omitted ⇒ the boxes are drawn all the same, and nothing says so.
|
|
229
|
+
*/
|
|
230
|
+
readonly losses?: Array<Loss>;
|
|
224
231
|
}
|
|
225
232
|
export type { DocumentInfo } from '../core/document-model/index.js';
|
|
226
233
|
/** A4 page width in points (the page-geometry fallback). */
|