@docx4j/core-ts 0.1.0 → 0.1.1
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 +410 -10
- package/dist/model/content/Body.d.mts +109 -4
- package/dist/model/content/Body.mjs +300 -29
- package/dist/model/content/Comment.d.mts +78 -0
- package/dist/model/content/Comment.mjs +429 -0
- package/dist/model/content/ContentControl.d.mts +173 -0
- package/dist/model/content/ContentControl.mjs +638 -0
- package/dist/model/content/Font.d.mts +48 -8
- package/dist/model/content/Font.mjs +55 -13
- package/dist/model/content/InlinePicture.d.mts +103 -0
- package/dist/model/content/InlinePicture.mjs +361 -0
- package/dist/model/content/List.d.mts +253 -0
- package/dist/model/content/List.mjs +778 -0
- package/dist/model/content/Paragraph.d.mts +213 -16
- package/dist/model/content/Paragraph.mjs +611 -57
- package/dist/model/content/Range.d.mts +48 -4
- package/dist/model/content/Range.mjs +161 -4
- package/dist/model/content/Table.d.mts +130 -0
- package/dist/model/content/Table.mjs +429 -0
- package/dist/model/content/TrackedChange.d.mts +96 -0
- package/dist/model/content/TrackedChange.mjs +352 -0
- package/dist/model/content/comments.d.mts +122 -0
- package/dist/model/content/comments.mjs +248 -0
- package/dist/model/content/index.d.mts +13 -3
- package/dist/model/content/index.mjs +15 -3
- package/dist/model/content/ooxml.d.mts +17 -0
- package/dist/model/content/ooxml.mjs +214 -0
- package/dist/model/content/styles.d.mts +21 -0
- package/dist/model/content/styles.mjs +86 -0
- package/dist/model/content/tracking.d.mts +104 -0
- package/dist/model/content/tracking.mjs +313 -0
- package/dist/model/content/tree.d.mts +56 -9
- package/dist/model/content/tree.mjs +104 -31
- package/dist/model/customxml/CustomXmlPart.d.mts +158 -0
- package/dist/model/customxml/CustomXmlPart.mjs +415 -0
- package/dist/model/customxml/CustomXmlPartCollection.d.mts +68 -0
- package/dist/model/customxml/CustomXmlPartCollection.mjs +183 -0
- package/dist/model/customxml/XmlMapping.d.mts +46 -0
- package/dist/model/customxml/XmlMapping.mjs +98 -0
- package/dist/model/customxml/bindings.d.mts +41 -0
- package/dist/model/customxml/bindings.mjs +230 -0
- package/dist/model/customxml/index.d.mts +7 -0
- package/dist/model/customxml/index.mjs +9 -0
- package/dist/model/customxml/insert.d.mts +20 -0
- package/dist/model/customxml/insert.mjs +22 -0
- package/dist/model/customxml/kinds.d.mts +103 -0
- package/dist/model/customxml/kinds.mjs +267 -0
- package/dist/model/customxml/xpath.d.mts +52 -0
- package/dist/model/customxml/xpath.mjs +205 -0
- package/dist/model/fonts/CJKToEnglish.d.mts +2 -0
- package/dist/model/fonts/CJKToEnglish.mjs +16 -0
- package/dist/model/fonts/FontFallback.d.mts +58 -0
- package/dist/model/fonts/FontFallback.mjs +219 -0
- package/dist/model/fonts/IdentityPlusMapper.d.mts +7 -0
- package/dist/model/fonts/IdentityPlusMapper.mjs +19 -0
- package/dist/model/fonts/LanguageTagToScriptMapping.d.mts +7 -0
- package/dist/model/fonts/LanguageTagToScriptMapping.mjs +67 -0
- package/dist/model/fonts/Mapper.d.mts +190 -0
- package/dist/model/fonts/Mapper.mjs +481 -0
- package/dist/model/fonts/PhysicalFont.d.mts +34 -0
- package/dist/model/fonts/PhysicalFont.mjs +62 -0
- package/dist/model/fonts/RunFontSelector.d.mts +194 -0
- package/dist/model/fonts/RunFontSelector.mjs +441 -0
- package/dist/model/fonts/ThemeFonts.d.mts +17 -0
- package/dist/model/fonts/ThemeFonts.mjs +76 -0
- package/dist/model/fonts/defaultTheme.d.mts +37 -0
- package/dist/model/fonts/defaultTheme.mjs +57 -0
- package/dist/model/fonts/families.generated.d.mts +11 -0
- package/dist/model/fonts/families.generated.mjs +17 -0
- package/dist/model/fonts/fontsInUse.d.mts +39 -0
- package/dist/model/fonts/fontsInUse.mjs +183 -0
- package/dist/model/fonts/index.d.mts +14 -0
- package/dist/model/fonts/index.mjs +29 -0
- package/dist/model/fonts/lookup.d.mts +5 -0
- package/dist/model/fonts/lookup.mjs +12 -0
- package/dist/model/fonts/registry.d.mts +31 -0
- package/dist/model/fonts/registry.mjs +103 -0
- package/dist/model/fonts/scripts.d.mts +2 -0
- package/dist/model/fonts/scripts.mjs +78 -0
- package/dist/model/fonts/substitutions.generated.d.mts +30 -0
- package/dist/model/fonts/substitutions.generated.mjs +12 -0
- package/dist/model/fonts/themes.generated.d.mts +6 -0
- package/dist/model/fonts/themes.generated.mjs +11 -0
- package/dist/model/index.d.mts +5 -0
- package/dist/model/index.mjs +13 -1
- package/dist/model/listnumbering/Emulator.d.mts +187 -0
- package/dist/model/listnumbering/Emulator.mjs +332 -0
- package/dist/model/listnumbering/definitions.d.mts +251 -0
- package/dist/model/listnumbering/definitions.mjs +571 -0
- package/dist/model/listnumbering/formats.d.mts +25 -0
- package/dist/model/listnumbering/formats.mjs +320 -0
- package/dist/model/listnumbering/index.d.mts +4 -0
- package/dist/model/listnumbering/index.mjs +15 -0
- package/dist/model/listnumbering/state.d.mts +97 -0
- package/dist/model/listnumbering/state.mjs +179 -0
- package/dist/model/properties/PropertyResolver.d.mts +216 -0
- package/dist/model/properties/PropertyResolver.mjs +524 -0
- package/dist/model/properties/catalogue.d.mts +179 -0
- package/dist/model/properties/catalogue.mjs +860 -0
- package/dist/model/properties/index.d.mts +4 -0
- package/dist/model/properties/index.mjs +9 -0
- package/dist/model/properties/log.d.mts +7 -0
- package/dist/model/properties/log.mjs +25 -0
- package/dist/model/properties/styleUtil.d.mts +112 -0
- package/dist/model/properties/styleUtil.mjs +359 -0
- package/dist/node/index.d.mts +1 -0
- package/dist/node/index.mjs +12 -0
- package/dist/office-js/document.d.mts +111 -0
- package/dist/office-js/document.mjs +267 -0
- package/dist/office-js/enums.d.mts +187 -0
- package/dist/office-js/enums.mjs +176 -0
- package/dist/office-js/errors.d.mts +29 -0
- package/dist/office-js/errors.mjs +39 -0
- package/dist/office-js/extras.d.mts +5 -0
- package/dist/office-js/extras.mjs +29 -0
- package/dist/office-js/fragment.d.mts +10 -0
- package/dist/office-js/fragment.mjs +23 -0
- package/dist/office-js/index.d.mts +183 -0
- package/dist/office-js/index.mjs +54 -0
- package/dist/office-js/proxy.d.mts +72 -0
- package/dist/office-js/proxy.mjs +279 -0
- package/dist/office-js/run.d.mts +32 -0
- package/dist/office-js/run.mjs +66 -0
- package/dist/office-js/supported.d.mts +7 -0
- package/dist/office-js/supported.generated.d.mts +1 -0
- package/dist/office-js/supported.generated.mjs +235 -0
- package/dist/office-js/supported.mjs +53 -0
- package/dist/office-js/toApiScript.d.mts +25 -0
- package/dist/office-js/toApiScript.mjs +394 -0
- package/dist/opc/ContentTypes.d.mts +1 -0
- package/dist/opc/ContentTypes.mjs +1 -0
- package/dist/opc/DirectoryPartStore.d.mts +47 -0
- package/dist/opc/DirectoryPartStore.mjs +123 -0
- package/dist/opc/exceptions.d.mts +30 -0
- package/dist/opc/exceptions.mjs +38 -0
- package/dist/opc/index.d.mts +1 -1
- package/dist/opc/index.mjs +1 -1
- package/dist/packages/OpcPackage.d.mts +19 -1
- package/dist/packages/OpcPackage.mjs +29 -0
- package/dist/packages/PresentationMLPackage.d.mts +71 -1
- package/dist/packages/PresentationMLPackage.mjs +179 -0
- package/dist/packages/SpreadsheetMLPackage.d.mts +30 -1
- package/dist/packages/SpreadsheetMLPackage.mjs +78 -0
- package/dist/packages/WordprocessingMLPackage.d.mts +124 -2
- package/dist/packages/WordprocessingMLPackage.mjs +309 -2
- package/dist/packages/index.d.mts +1 -1
- package/dist/packages/index.mjs +1 -1
- package/dist/parts/DefaultXmlPart.d.mts +18 -0
- package/dist/parts/DefaultXmlPart.mjs +34 -5
- package/dist/parts/PartRegistry.mjs +1 -0
- package/dist/parts/XmlPart.d.mts +33 -0
- package/dist/parts/XmlPart.mjs +105 -2
- package/dist/parts/pml/defaults.d.mts +6 -0
- package/dist/parts/pml/defaults.mjs +53 -0
- package/dist/parts/pml/index.d.mts +66 -3
- package/dist/parts/pml/index.mjs +206 -7
- package/dist/parts/pml/placeholders.d.mts +71 -0
- package/dist/parts/pml/placeholders.mjs +141 -0
- package/dist/parts/sml/index.d.mts +19 -1
- package/dist/parts/sml/index.mjs +60 -1
- package/dist/parts/wml/comments.d.mts +1 -0
- package/dist/parts/wml/comments.mjs +179 -0
- package/dist/parts/wml/defaultNumbering.d.mts +1 -0
- package/dist/parts/wml/defaultNumbering.mjs +216 -0
- package/dist/parts/wml/index.d.mts +121 -0
- package/dist/parts/wml/index.mjs +291 -0
- package/dist/xml/dom.mjs +1 -2
- package/package.json +25 -4
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
2
|
+
import type { PropertyResolver } from '../properties/PropertyResolver.mjs';
|
|
3
|
+
import { type ThemeFontLang, type ThemeSource } from './ThemeFonts.mjs';
|
|
4
|
+
import { type DefaultTheme } from './defaultTheme.mjs';
|
|
5
|
+
/** Word's built-in default where the document defaults name no font at all (docx4j CR-016
|
|
6
|
+
* probe `fonts-missing-slots` (a)). */
|
|
7
|
+
export declare const BUILT_IN_DEFAULT_FONT = "Times New Roman";
|
|
8
|
+
/** One stretch of a run's text set in one document font. */
|
|
9
|
+
export interface FontSpan {
|
|
10
|
+
/** The text of the span. */
|
|
11
|
+
readonly text: string;
|
|
12
|
+
/** The document font (the name a `w:rFonts` slot gives, theme reference resolved); null
|
|
13
|
+
* where the run names no font at all and there is no default either. */
|
|
14
|
+
readonly documentFont: string | null;
|
|
15
|
+
readonly bold: boolean;
|
|
16
|
+
readonly italic: boolean;
|
|
17
|
+
/** `w:cs` of the effective run properties, by value. */
|
|
18
|
+
readonly cs: boolean;
|
|
19
|
+
/** `w:rtl` of the effective run properties, by value. */
|
|
20
|
+
readonly rtl: boolean;
|
|
21
|
+
/** The span's script, as `spanScript` groups it (`LATIN`, `CJK`, `SYMBOL`, `EMOJI`, ...);
|
|
22
|
+
* null where every character of the span is shared (a space, a digit, punctuation). */
|
|
23
|
+
readonly script: string | null;
|
|
24
|
+
}
|
|
25
|
+
/** What the selector reads. Structural, so this module imports no part class. */
|
|
26
|
+
export interface RunFontSelectorSource {
|
|
27
|
+
/** The package's resolver; without one, the properties passed in are taken as they are. */
|
|
28
|
+
resolver?: PropertyResolver | undefined;
|
|
29
|
+
/** The theme part's `a:theme` (or its font scheme); absent for a package with no theme part. */
|
|
30
|
+
theme?: ThemeSource;
|
|
31
|
+
/** `w:themeFontLang` from the settings part. */
|
|
32
|
+
themeFontLang?: ThemeFontLang | undefined;
|
|
33
|
+
/** Which Office theme answers a reference where there is no theme part; the process-wide
|
|
34
|
+
* `defaultThemeSetting()` by default. */
|
|
35
|
+
defaultTheme?: DefaultTheme | undefined;
|
|
36
|
+
/** The face to use for an astral emoji, docx4j's `docx4j.fonts.RunFontSelector.EmojiFont`.
|
|
37
|
+
* Unset by default, as docx4j's property is, so an emoji takes the hAnsi font. */
|
|
38
|
+
emojiFont?: string | undefined;
|
|
39
|
+
}
|
|
40
|
+
/** `spans()` options. */
|
|
41
|
+
export interface SpansOptions {
|
|
42
|
+
/** True where the caller has resolved the run's effective properties already. */
|
|
43
|
+
rPrIsEffective?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** `w:cs` and `w:rtl` are `ST_OnOff`: present without `w:val` means true, `w:val="0"` false. */
|
|
46
|
+
export declare function isOn(value: wml.BooleanDefaultTrue | undefined): boolean;
|
|
47
|
+
/** The canonical name of one of the symbol fonts, whatever case the document wrote it in;
|
|
48
|
+
* undefined for any other font. Font names are case-insensitive, and Word draws 'symbol'
|
|
49
|
+
* with Symbol (docx4j CR-016 probe `fonts-symbol-and-emoji` (a), (b)). */
|
|
50
|
+
export declare function symbolFontName(documentFontName: string | undefined): string | undefined;
|
|
51
|
+
/** The emoji blocks - Mahjong, Domino and Playing Card tiles, the enclosed alphanumerics and
|
|
52
|
+
* ideographs, Miscellaneous Symbols and Pictographs, Emoticons, Transport and Map, the
|
|
53
|
+
* supplemental and extended symbol blocks. Word sets them in Segoe UI Emoji. */
|
|
54
|
+
export declare function isEmoji(cp: number): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* The group a span is cut by: the coverage group of the code point (its Unicode script, or
|
|
57
|
+
* SYMBOL / EMOJI), the CJK scripts as one, and null for a shared character (COMMON,
|
|
58
|
+
* INHERITED), which joins whatever it follows.
|
|
59
|
+
*
|
|
60
|
+
* docx4j's rendering walk cuts a span where the *script* changes between two non-shared
|
|
61
|
+
* characters as well as where the font does, so that a Greek stretch inside a Latin font is
|
|
62
|
+
* substituted as one top-level span; measured, nesting it changed FOP's line stacking and cost
|
|
63
|
+
* a corpus document a page. {@link RunFontSelector.spans} folds by font alone (which is what
|
|
64
|
+
* `documentFontFor` per code point answers, and what the parity goldens record) and reports the
|
|
65
|
+
* script, so a renderer can cut further.
|
|
66
|
+
*/
|
|
67
|
+
export declare function spanScript(cp: number): string | null;
|
|
68
|
+
/** The table's preamble: an eastAsia of Times New Roman with ascii and hAnsi equal sets the
|
|
69
|
+
* whole run in the ascii font. */
|
|
70
|
+
export declare function preambleRule(eastAsia: string | undefined, ascii: string | undefined, hAnsi: string | undefined): boolean;
|
|
71
|
+
/** The run's language, for case conversion: `w:lang/@w:val`, else undefined (the root locale). */
|
|
72
|
+
export declare function runLocale(rPr: wml.RPr | undefined): string | undefined;
|
|
73
|
+
export declare class RunFontSelector {
|
|
74
|
+
private readonly source;
|
|
75
|
+
constructor(source?: RunFontSelectorSource);
|
|
76
|
+
private defaultFontCache;
|
|
77
|
+
/** Which Office theme answers a reference where the package has no theme part. */
|
|
78
|
+
get defaultTheme(): DefaultTheme;
|
|
79
|
+
/**
|
|
80
|
+
* The face a theme reference names: the theme part's answer for the document's
|
|
81
|
+
* `themeFontLang`; or, where the document has **no theme part**, the Office theme's own Latin
|
|
82
|
+
* faces - Word supplies that theme to such a document, and the explicit `w:ascii` beside the
|
|
83
|
+
* reference is unused (docx4j CR-016 probe `fonts-missing-slots` (b)).
|
|
84
|
+
*
|
|
85
|
+
* Only the two Latin slots are answered in the themeless case: the Office theme's East Asian
|
|
86
|
+
* and complex-script entries are empty, so those references resolve to nothing and the
|
|
87
|
+
* explicit attribute, if any, stands. Which Latin faces they are is
|
|
88
|
+
* {@link RunFontSelector.defaultTheme}.
|
|
89
|
+
*/
|
|
90
|
+
themeFont(type: wml.STTheme | undefined): string | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* The document fonts an `rFonts` names once its theme references are resolved: for each of
|
|
93
|
+
* the four slots, the theme's face, else the explicit attribute. Blank names are left out.
|
|
94
|
+
* This is what font discovery collects (`MainDocumentPart.fontsInUse()`).
|
|
95
|
+
*/
|
|
96
|
+
documentFontsOf(rFonts: wml.RFonts | undefined): string[];
|
|
97
|
+
/**
|
|
98
|
+
* The document's default font for Latin text: the document defaults' `w:ascii` (a theme
|
|
99
|
+
* reference resolved first), else `w:hAnsi`; Times New Roman where the defaults name no font
|
|
100
|
+
* at all. A theme reference the theme cannot answer gives Calibri, as docx4j's does.
|
|
101
|
+
*/
|
|
102
|
+
defaultFontOf(docDefaultsRFonts: wml.RFonts | undefined): string;
|
|
103
|
+
/** {@link defaultFontOf} of the document defaults the resolver holds, computed once. */
|
|
104
|
+
get defaultFont(): string;
|
|
105
|
+
/** Forget the cached default font: the styles part changed under us. */
|
|
106
|
+
refresh(): void;
|
|
107
|
+
/**
|
|
108
|
+
* The document font an `rPr` asks for its ASCII text: `w:ascii`, or the face `w:asciiTheme`
|
|
109
|
+
* names; failing those `w:hAnsi`, and failing that the document default. Never empty.
|
|
110
|
+
*
|
|
111
|
+
* This is what a *name* is - what Office JS's `font.name` reports and what docx4j uses for
|
|
112
|
+
* the line metrics of generated text and paragraph marks. It is not the dispatch: a run of
|
|
113
|
+
* Arabic in a font named here may still be drawn in the cs font
|
|
114
|
+
* ({@link RunFontSelector.documentFontFor}).
|
|
115
|
+
*/
|
|
116
|
+
asciiFontName(rPr: wml.RPr | undefined): string;
|
|
117
|
+
/** The run's effective properties, never undefined. */
|
|
118
|
+
private effectiveRPr;
|
|
119
|
+
/**
|
|
120
|
+
* The run's `w:rFonts`, or where nothing anywhere names a font, the document default for the
|
|
121
|
+
* ascii and hAnsi slots, the East Asian and complex-script slots left unnamed as for any run
|
|
122
|
+
* that never named them, and then the range dispatch as for any other run. (Not the eastAsia
|
|
123
|
+
* slot: a Times New Roman there would fire the preamble rule and set the whole run in one
|
|
124
|
+
* span.)
|
|
125
|
+
*/
|
|
126
|
+
private rFontsOf;
|
|
127
|
+
/**
|
|
128
|
+
* The complex-script font the run is set in as a whole, where `w:cs` or `w:rtl` is **on** and
|
|
129
|
+
* the cs slot names a font (the theme reference resolved first, else the attribute);
|
|
130
|
+
* undefined where the run is dispatched by range instead - neither is on, or the reference
|
|
131
|
+
* resolves to nothing and there is no `w:cs`.
|
|
132
|
+
*/
|
|
133
|
+
complexScriptFont(rPr: wml.RPr, rFonts: wml.RFonts): string | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* The four slots resolved: each the theme reference where there is one, else the explicit
|
|
136
|
+
* attribute (which also stands where the reference resolves to nothing). Order: eastAsia,
|
|
137
|
+
* ascii, hAnsi, cs.
|
|
138
|
+
*/
|
|
139
|
+
resolvedSlots(rFonts: wml.RFonts): [string | undefined, string | undefined, string | undefined, string | undefined];
|
|
140
|
+
/** The run's slots, ready for {@link fontFor}: the body of docx4j's `fontSelector` before the
|
|
141
|
+
* walk, shared by {@link documentFontFor} and {@link spans}. */
|
|
142
|
+
private slotsOf;
|
|
143
|
+
private fontOf;
|
|
144
|
+
/**
|
|
145
|
+
* The document font the selector picks for one code point in a run with these properties: the
|
|
146
|
+
* symbol font by its canonical name where the run's hAnsi is one, the complex-script font
|
|
147
|
+
* where `w:cs` or `w:rtl` is on and names one, the ascii font under the preamble rule, else
|
|
148
|
+
* the font the character-range table gives the code point. Never null: the document default
|
|
149
|
+
* at least.
|
|
150
|
+
*
|
|
151
|
+
* @param rPrIsEffective true where the caller has resolved the run's properties already
|
|
152
|
+
*/
|
|
153
|
+
documentFontFor(pPr: wml.PPr | undefined, rPr: wml.RPr | undefined, codePoint: number, rPrIsEffective?: boolean): string;
|
|
154
|
+
/**
|
|
155
|
+
* The run's text folded into maximal stretches of one document font.
|
|
156
|
+
*
|
|
157
|
+
* Every code point is asked for its font ({@link documentFontFor}) and joins the span being
|
|
158
|
+
* built while the answer is the same, whatever its range - docx4j's walk since 17.1.1, which
|
|
159
|
+
* replaced cutting by *range* (a Latin run was cut at every exception character, a space went
|
|
160
|
+
* to the East Asian font of the word before it, and the ASCII letters after an accented one
|
|
161
|
+
* stayed in the hAnsi font). `bold`, `italic`, `cs` and `rtl` are the effective run
|
|
162
|
+
* properties' and are the same for every span of a run.
|
|
163
|
+
*/
|
|
164
|
+
spans(pPr: wml.PPr | undefined, rPr: wml.RPr | undefined, text: string | undefined, options?: SpansOptions): FontSpan[];
|
|
165
|
+
/**
|
|
166
|
+
* The document font which formats one code point, given the run's four fonts (each already
|
|
167
|
+
* resolved through the theme) and its hint: the table in [MS-OI29500] 17.3.2.26, with these
|
|
168
|
+
* departures from it, each measured by docx4j:
|
|
169
|
+
*
|
|
170
|
+
* - the Indic, Thai, Lao, Myanmar and Khmer ranges use cs, where the table says hAnsi
|
|
171
|
+
* (docx4j issues 622 and 666);
|
|
172
|
+
* - an East Asian reference is "eastAsia (or eastAsiaTheme) if defined": a run naming none
|
|
173
|
+
* gets hAnsi in those places, never nothing;
|
|
174
|
+
* - characters outside the Basic Multilingual Plane, which the table does not cover: the
|
|
175
|
+
* {@link RunFontSelectorSource.emojiFont} where one is configured, else hAnsi (Word uses
|
|
176
|
+
* Segoe UI Emoji, which docx4j's coverage pass finds).
|
|
177
|
+
*
|
|
178
|
+
* What the table says and Word confirmed: U+0020 is ASCII and takes the ascii font, so the
|
|
179
|
+
* space between two East Asian words is the Latin font's; Hebrew, Arabic and the rest of
|
|
180
|
+
* U+0590-U+07BF in a run with no `w:cs` take the ascii font. The table's other condition for
|
|
181
|
+
* U+0100-U+02AF and U+1E00-U+1EFF under `hint=eastAsia`, "or the character set of the
|
|
182
|
+
* eastAsia font is Chinese5 or GB2312", needs the font's OS/2 code-page bits and is not
|
|
183
|
+
* implemented here either.
|
|
184
|
+
*
|
|
185
|
+
* **U+2190-U+2BFF**: docx4j asks whether the hAnsi font has the glyph and names Segoe UI
|
|
186
|
+
* Symbol where it does not. That is a glyph check over a font file, which this CR does not
|
|
187
|
+
* port (CR-001 section 14.2), so the hAnsi font is answered - which is also docx4j's answer
|
|
188
|
+
* wherever Segoe UI Symbol is not among the fonts it has, the environment the parity goldens
|
|
189
|
+
* record.
|
|
190
|
+
*
|
|
191
|
+
* @returns a document font name; undefined only where the run names no hAnsi font either
|
|
192
|
+
*/
|
|
193
|
+
fontFor(cp: number, hint: wml.STHint | undefined, langEastAsia: string | undefined, eastAsia: string | undefined, ascii: string | undefined, hAnsi: string | undefined, cs: string | undefined): string | undefined;
|
|
194
|
+
}
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { themeFontOf } from './ThemeFonts.mjs';
|
|
2
|
+
import { defaultThemeSetting } from './defaultTheme.mjs';
|
|
3
|
+
import { coverageGroupOf } from './FontFallback.mjs';
|
|
4
|
+
/** Word's built-in default where the document defaults name no font at all (docx4j CR-016
|
|
5
|
+
* probe `fonts-missing-slots` (a)). */
|
|
6
|
+
export const BUILT_IN_DEFAULT_FONT = 'Times New Roman';
|
|
7
|
+
/** The fonts `symbolFontName` recognises; docx4j's `SymbolMapper` knows these five. */
|
|
8
|
+
const SYMBOL_FONTS = ['Symbol', 'Webdings', 'Wingdings', 'Wingdings 2', 'Wingdings 3'];
|
|
9
|
+
/** `w:cs` and `w:rtl` are `ST_OnOff`: present without `w:val` means true, `w:val="0"` false. */
|
|
10
|
+
export function isOn(value) {
|
|
11
|
+
return value !== undefined && value !== null && value.val !== false;
|
|
12
|
+
}
|
|
13
|
+
/** The canonical name of one of the symbol fonts, whatever case the document wrote it in;
|
|
14
|
+
* undefined for any other font. Font names are case-insensitive, and Word draws 'symbol'
|
|
15
|
+
* with Symbol (docx4j CR-016 probe `fonts-symbol-and-emoji` (a), (b)). */
|
|
16
|
+
export function symbolFontName(documentFontName) {
|
|
17
|
+
if (documentFontName === undefined || documentFontName === null)
|
|
18
|
+
return undefined;
|
|
19
|
+
const name = documentFontName.trim().toLowerCase();
|
|
20
|
+
return SYMBOL_FONTS.find((known) => known.toLowerCase() === name);
|
|
21
|
+
}
|
|
22
|
+
/** The emoji blocks - Mahjong, Domino and Playing Card tiles, the enclosed alphanumerics and
|
|
23
|
+
* ideographs, Miscellaneous Symbols and Pictographs, Emoticons, Transport and Map, the
|
|
24
|
+
* supplemental and extended symbol blocks. Word sets them in Segoe UI Emoji. */
|
|
25
|
+
export function isEmoji(cp) {
|
|
26
|
+
return cp >= 0x1F000 && cp <= 0x1FAFF;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The group a span is cut by: the coverage group of the code point (its Unicode script, or
|
|
30
|
+
* SYMBOL / EMOJI), the CJK scripts as one, and null for a shared character (COMMON,
|
|
31
|
+
* INHERITED), which joins whatever it follows.
|
|
32
|
+
*
|
|
33
|
+
* docx4j's rendering walk cuts a span where the *script* changes between two non-shared
|
|
34
|
+
* characters as well as where the font does, so that a Greek stretch inside a Latin font is
|
|
35
|
+
* substituted as one top-level span; measured, nesting it changed FOP's line stacking and cost
|
|
36
|
+
* a corpus document a page. {@link RunFontSelector.spans} folds by font alone (which is what
|
|
37
|
+
* `documentFontFor` per code point answers, and what the parity goldens record) and reports the
|
|
38
|
+
* script, so a renderer can cut further.
|
|
39
|
+
*/
|
|
40
|
+
export function spanScript(cp) {
|
|
41
|
+
const group = coverageGroupOf(cp);
|
|
42
|
+
if (group === 'COMMON' || group === 'INHERITED')
|
|
43
|
+
return null;
|
|
44
|
+
if (group === 'HAN' || group === 'HIRAGANA' || group === 'KATAKANA' || group === 'HANGUL'
|
|
45
|
+
|| group === 'BOPOMOFO')
|
|
46
|
+
return 'CJK';
|
|
47
|
+
return group;
|
|
48
|
+
}
|
|
49
|
+
/** The table's preamble: an eastAsia of Times New Roman with ascii and hAnsi equal sets the
|
|
50
|
+
* whole run in the ascii font. */
|
|
51
|
+
export function preambleRule(eastAsia, ascii, hAnsi) {
|
|
52
|
+
return eastAsia === 'Times New Roman' && ascii !== undefined && ascii === hAnsi;
|
|
53
|
+
}
|
|
54
|
+
/** The run's language, for case conversion: `w:lang/@w:val`, else undefined (the root locale). */
|
|
55
|
+
export function runLocale(rPr) {
|
|
56
|
+
var _a;
|
|
57
|
+
const tag = (_a = rPr === null || rPr === void 0 ? void 0 : rPr.lang) === null || _a === void 0 ? void 0 : _a.val;
|
|
58
|
+
return tag !== undefined && tag.length > 0 ? tag : undefined;
|
|
59
|
+
}
|
|
60
|
+
function contains(langEastAsia, lang) {
|
|
61
|
+
// eg <w:lang w:eastAsia="zh-CN" .. />
|
|
62
|
+
return langEastAsia !== undefined && langEastAsia.includes(lang);
|
|
63
|
+
}
|
|
64
|
+
export class RunFontSelector {
|
|
65
|
+
constructor(source = {}) {
|
|
66
|
+
this.source = source;
|
|
67
|
+
}
|
|
68
|
+
/** Which Office theme answers a reference where the package has no theme part. */
|
|
69
|
+
get defaultTheme() {
|
|
70
|
+
var _a;
|
|
71
|
+
return (_a = this.source.defaultTheme) !== null && _a !== void 0 ? _a : defaultThemeSetting();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The face a theme reference names: the theme part's answer for the document's
|
|
75
|
+
* `themeFontLang`; or, where the document has **no theme part**, the Office theme's own Latin
|
|
76
|
+
* faces - Word supplies that theme to such a document, and the explicit `w:ascii` beside the
|
|
77
|
+
* reference is unused (docx4j CR-016 probe `fonts-missing-slots` (b)).
|
|
78
|
+
*
|
|
79
|
+
* Only the two Latin slots are answered in the themeless case: the Office theme's East Asian
|
|
80
|
+
* and complex-script entries are empty, so those references resolve to nothing and the
|
|
81
|
+
* explicit attribute, if any, stands. Which Latin faces they are is
|
|
82
|
+
* {@link RunFontSelector.defaultTheme}.
|
|
83
|
+
*/
|
|
84
|
+
themeFont(type) {
|
|
85
|
+
if (type === undefined || type === null)
|
|
86
|
+
return undefined;
|
|
87
|
+
if (this.source.theme !== undefined) {
|
|
88
|
+
return themeFontOf(this.source.theme, type, this.source.themeFontLang);
|
|
89
|
+
}
|
|
90
|
+
switch (type) {
|
|
91
|
+
case 'minorAscii':
|
|
92
|
+
case 'minorHAnsi': return this.defaultTheme.minorLatin;
|
|
93
|
+
case 'majorAscii':
|
|
94
|
+
case 'majorHAnsi': return this.defaultTheme.majorLatin;
|
|
95
|
+
default: return undefined;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The document fonts an `rFonts` names once its theme references are resolved: for each of
|
|
100
|
+
* the four slots, the theme's face, else the explicit attribute. Blank names are left out.
|
|
101
|
+
* This is what font discovery collects (`MainDocumentPart.fontsInUse()`).
|
|
102
|
+
*/
|
|
103
|
+
documentFontsOf(rFonts) {
|
|
104
|
+
var _a;
|
|
105
|
+
const names = [];
|
|
106
|
+
if (rFonts === undefined || rFonts === null)
|
|
107
|
+
return names;
|
|
108
|
+
const refs = [rFonts.asciiTheme, rFonts.hAnsiTheme, rFonts.eastAsiaTheme, rFonts.cstheme];
|
|
109
|
+
const explicit = [rFonts.ascii, rFonts.hAnsi, rFonts.eastAsia, rFonts.cs];
|
|
110
|
+
for (let i = 0; i < 4; i++) {
|
|
111
|
+
const name = (_a = this.themeFont(refs[i])) !== null && _a !== void 0 ? _a : explicit[i];
|
|
112
|
+
if (name !== undefined && name.trim().length > 0)
|
|
113
|
+
names.push(name.trim());
|
|
114
|
+
}
|
|
115
|
+
return names;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The document's default font for Latin text: the document defaults' `w:ascii` (a theme
|
|
119
|
+
* reference resolved first), else `w:hAnsi`; Times New Roman where the defaults name no font
|
|
120
|
+
* at all. A theme reference the theme cannot answer gives Calibri, as docx4j's does.
|
|
121
|
+
*/
|
|
122
|
+
defaultFontOf(docDefaultsRFonts) {
|
|
123
|
+
let f;
|
|
124
|
+
if (docDefaultsRFonts !== undefined && docDefaultsRFonts !== null) {
|
|
125
|
+
const rFonts = docDefaultsRFonts;
|
|
126
|
+
if (rFonts.asciiTheme !== undefined)
|
|
127
|
+
f = this.themeFont(rFonts.asciiTheme);
|
|
128
|
+
if (f === undefined)
|
|
129
|
+
f = rFonts.ascii;
|
|
130
|
+
if (f === undefined && rFonts.asciiTheme !== undefined) {
|
|
131
|
+
// a theme reference the theme part cannot answer (an empty typeface)
|
|
132
|
+
f = 'Calibri';
|
|
133
|
+
}
|
|
134
|
+
if (f === undefined && rFonts.hAnsiTheme !== undefined)
|
|
135
|
+
f = this.themeFont(rFonts.hAnsiTheme);
|
|
136
|
+
if (f === undefined)
|
|
137
|
+
f = rFonts.hAnsi;
|
|
138
|
+
}
|
|
139
|
+
return f !== null && f !== void 0 ? f : BUILT_IN_DEFAULT_FONT;
|
|
140
|
+
}
|
|
141
|
+
/** {@link defaultFontOf} of the document defaults the resolver holds, computed once. */
|
|
142
|
+
get defaultFont() {
|
|
143
|
+
var _a, _b, _c;
|
|
144
|
+
(_a = this.defaultFontCache) !== null && _a !== void 0 ? _a : (this.defaultFontCache = this.defaultFontOf((_c = (_b = this.source.resolver) === null || _b === void 0 ? void 0 : _b.getDocumentDefaultRPr()) === null || _c === void 0 ? void 0 : _c.rFonts));
|
|
145
|
+
return this.defaultFontCache;
|
|
146
|
+
}
|
|
147
|
+
/** Forget the cached default font: the styles part changed under us. */
|
|
148
|
+
refresh() {
|
|
149
|
+
this.defaultFontCache = undefined;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The document font an `rPr` asks for its ASCII text: `w:ascii`, or the face `w:asciiTheme`
|
|
153
|
+
* names; failing those `w:hAnsi`, and failing that the document default. Never empty.
|
|
154
|
+
*
|
|
155
|
+
* This is what a *name* is - what Office JS's `font.name` reports and what docx4j uses for
|
|
156
|
+
* the line metrics of generated text and paragraph marks. It is not the dispatch: a run of
|
|
157
|
+
* Arabic in a font named here may still be drawn in the cs font
|
|
158
|
+
* ({@link RunFontSelector.documentFontFor}).
|
|
159
|
+
*/
|
|
160
|
+
asciiFontName(rPr) {
|
|
161
|
+
const rFonts = rPr === null || rPr === void 0 ? void 0 : rPr.rFonts;
|
|
162
|
+
if (rFonts !== undefined && rFonts !== null) {
|
|
163
|
+
if (rFonts.asciiTheme !== undefined) {
|
|
164
|
+
const f = this.themeFont(rFonts.asciiTheme);
|
|
165
|
+
if (f !== undefined && f.length > 0)
|
|
166
|
+
return f;
|
|
167
|
+
}
|
|
168
|
+
if (rFonts.ascii !== undefined)
|
|
169
|
+
return rFonts.ascii;
|
|
170
|
+
if (rFonts.hAnsi !== undefined)
|
|
171
|
+
return rFonts.hAnsi;
|
|
172
|
+
}
|
|
173
|
+
return this.defaultFont;
|
|
174
|
+
}
|
|
175
|
+
/** The run's effective properties, never undefined. */
|
|
176
|
+
effectiveRPr(pPr, rPr, rPrIsEffective) {
|
|
177
|
+
var _a;
|
|
178
|
+
if (!rPrIsEffective && this.source.resolver !== undefined) {
|
|
179
|
+
return (_a = this.source.resolver.getEffectiveRPr(rPr, pPr)) !== null && _a !== void 0 ? _a : {};
|
|
180
|
+
}
|
|
181
|
+
return rPr !== null && rPr !== void 0 ? rPr : {};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* The run's `w:rFonts`, or where nothing anywhere names a font, the document default for the
|
|
185
|
+
* ascii and hAnsi slots, the East Asian and complex-script slots left unnamed as for any run
|
|
186
|
+
* that never named them, and then the range dispatch as for any other run. (Not the eastAsia
|
|
187
|
+
* slot: a Times New Roman there would fire the preamble rule and set the whole run in one
|
|
188
|
+
* span.)
|
|
189
|
+
*/
|
|
190
|
+
rFontsOf(rPr) {
|
|
191
|
+
const rFonts = rPr.rFonts;
|
|
192
|
+
if (rFonts !== undefined && rFonts !== null)
|
|
193
|
+
return rFonts;
|
|
194
|
+
return { ascii: this.defaultFont, hAnsi: this.defaultFont };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The complex-script font the run is set in as a whole, where `w:cs` or `w:rtl` is **on** and
|
|
198
|
+
* the cs slot names a font (the theme reference resolved first, else the attribute);
|
|
199
|
+
* undefined where the run is dispatched by range instead - neither is on, or the reference
|
|
200
|
+
* resolves to nothing and there is no `w:cs`.
|
|
201
|
+
*/
|
|
202
|
+
complexScriptFont(rPr, rFonts) {
|
|
203
|
+
var _a;
|
|
204
|
+
if (!isOn(rPr.cs) && !isOn(rPr.rtl))
|
|
205
|
+
return undefined;
|
|
206
|
+
if (rFonts.cstheme !== undefined)
|
|
207
|
+
return (_a = this.themeFont(rFonts.cstheme)) !== null && _a !== void 0 ? _a : rFonts.cs;
|
|
208
|
+
return rFonts.cs; // undefined: no CS value, dispatched by range
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The four slots resolved: each the theme reference where there is one, else the explicit
|
|
212
|
+
* attribute (which also stands where the reference resolves to nothing). Order: eastAsia,
|
|
213
|
+
* ascii, hAnsi, cs.
|
|
214
|
+
*/
|
|
215
|
+
resolvedSlots(rFonts) {
|
|
216
|
+
var _a, _b, _c, _d;
|
|
217
|
+
const eastAsia = (_a = this.themeFont(rFonts.eastAsiaTheme)) !== null && _a !== void 0 ? _a : rFonts.eastAsia;
|
|
218
|
+
const ascii = (_b = this.themeFont(rFonts.asciiTheme)) !== null && _b !== void 0 ? _b : rFonts.ascii;
|
|
219
|
+
const hAnsi = (_c = this.themeFont(rFonts.hAnsiTheme)) !== null && _c !== void 0 ? _c : rFonts.hAnsi;
|
|
220
|
+
let cs = (_d = this.themeFont(rFonts.cstheme)) !== null && _d !== void 0 ? _d : rFonts.cs;
|
|
221
|
+
// eg LibreOffice writes w:cs="" in docDefaults
|
|
222
|
+
if (cs !== undefined && cs.trim().length === 0)
|
|
223
|
+
cs = undefined;
|
|
224
|
+
return [eastAsia, ascii, hAnsi, cs];
|
|
225
|
+
}
|
|
226
|
+
/** The run's slots, ready for {@link fontFor}: the body of docx4j's `fontSelector` before the
|
|
227
|
+
* walk, shared by {@link documentFontFor} and {@link spans}. */
|
|
228
|
+
slotsOf(pPr, rPr) {
|
|
229
|
+
var _a;
|
|
230
|
+
const rFonts = this.rFontsOf(rPr);
|
|
231
|
+
const symbolFont = symbolFontName(rFonts.hAnsi);
|
|
232
|
+
if (symbolFont !== undefined)
|
|
233
|
+
return { single: symbolFont };
|
|
234
|
+
const csFont = this.complexScriptFont(rPr, rFonts);
|
|
235
|
+
if (csFont !== undefined)
|
|
236
|
+
return { single: csFont };
|
|
237
|
+
const [eastAsia, ascii0, hAnsi0, cs] = this.resolvedSlots(rFonts);
|
|
238
|
+
if (preambleRule(eastAsia, ascii0, hAnsi0))
|
|
239
|
+
return { single: ascii0 };
|
|
240
|
+
return {
|
|
241
|
+
eastAsia,
|
|
242
|
+
ascii: ascii0 !== null && ascii0 !== void 0 ? ascii0 : this.defaultFont,
|
|
243
|
+
hAnsi: hAnsi0 !== null && hAnsi0 !== void 0 ? hAnsi0 : this.defaultFont,
|
|
244
|
+
cs,
|
|
245
|
+
hint: rFonts.hint,
|
|
246
|
+
langEastAsia: (_a = rPr.lang) === null || _a === void 0 ? void 0 : _a.eastAsia,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
fontOf(slots, cp) {
|
|
250
|
+
if (slots.single !== undefined)
|
|
251
|
+
return slots.single;
|
|
252
|
+
return this.fontFor(cp, slots.hint, slots.langEastAsia, slots.eastAsia, slots.ascii, slots.hAnsi, slots.cs);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The document font the selector picks for one code point in a run with these properties: the
|
|
256
|
+
* symbol font by its canonical name where the run's hAnsi is one, the complex-script font
|
|
257
|
+
* where `w:cs` or `w:rtl` is on and names one, the ascii font under the preamble rule, else
|
|
258
|
+
* the font the character-range table gives the code point. Never null: the document default
|
|
259
|
+
* at least.
|
|
260
|
+
*
|
|
261
|
+
* @param rPrIsEffective true where the caller has resolved the run's properties already
|
|
262
|
+
*/
|
|
263
|
+
documentFontFor(pPr, rPr, codePoint, rPrIsEffective = false) {
|
|
264
|
+
var _a;
|
|
265
|
+
const effective = this.effectiveRPr(pPr, rPr, rPrIsEffective);
|
|
266
|
+
return (_a = this.fontOf(this.slotsOf(pPr, effective), codePoint)) !== null && _a !== void 0 ? _a : this.defaultFont;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* The run's text folded into maximal stretches of one document font.
|
|
270
|
+
*
|
|
271
|
+
* Every code point is asked for its font ({@link documentFontFor}) and joins the span being
|
|
272
|
+
* built while the answer is the same, whatever its range - docx4j's walk since 17.1.1, which
|
|
273
|
+
* replaced cutting by *range* (a Latin run was cut at every exception character, a space went
|
|
274
|
+
* to the East Asian font of the word before it, and the ASCII letters after an accented one
|
|
275
|
+
* stayed in the hAnsi font). `bold`, `italic`, `cs` and `rtl` are the effective run
|
|
276
|
+
* properties' and are the same for every span of a run.
|
|
277
|
+
*/
|
|
278
|
+
spans(pPr, rPr, text, options = {}) {
|
|
279
|
+
var _a;
|
|
280
|
+
const spans = [];
|
|
281
|
+
if (text === undefined || text === null || text.length === 0)
|
|
282
|
+
return spans;
|
|
283
|
+
const effective = this.effectiveRPr(pPr, rPr, options.rPrIsEffective === true);
|
|
284
|
+
const bold = isOn(effective.b);
|
|
285
|
+
const italic = isOn(effective.i);
|
|
286
|
+
const cs = isOn(effective.cs);
|
|
287
|
+
const rtl = isOn(effective.rtl);
|
|
288
|
+
const slots = this.slotsOf(pPr, effective);
|
|
289
|
+
const memo = new Map();
|
|
290
|
+
let current = '';
|
|
291
|
+
let currentFont;
|
|
292
|
+
let currentScript = null;
|
|
293
|
+
const flush = () => {
|
|
294
|
+
if (currentFont === undefined)
|
|
295
|
+
return;
|
|
296
|
+
spans.push({ text: current, documentFont: currentFont, bold, italic, cs, rtl, script: currentScript });
|
|
297
|
+
};
|
|
298
|
+
for (const ch of text) {
|
|
299
|
+
const cp = ch.codePointAt(0);
|
|
300
|
+
let font = memo.get(cp);
|
|
301
|
+
if (font === undefined) {
|
|
302
|
+
font = (_a = this.fontOf(slots, cp)) !== null && _a !== void 0 ? _a : null;
|
|
303
|
+
memo.set(cp, font);
|
|
304
|
+
}
|
|
305
|
+
if (currentFont !== undefined && currentFont !== font) {
|
|
306
|
+
flush();
|
|
307
|
+
current = '';
|
|
308
|
+
currentScript = null;
|
|
309
|
+
}
|
|
310
|
+
currentFont = font;
|
|
311
|
+
const script = spanScript(cp);
|
|
312
|
+
if (script !== null && currentScript === null)
|
|
313
|
+
currentScript = script;
|
|
314
|
+
current += ch;
|
|
315
|
+
}
|
|
316
|
+
flush();
|
|
317
|
+
return spans;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* The document font which formats one code point, given the run's four fonts (each already
|
|
321
|
+
* resolved through the theme) and its hint: the table in [MS-OI29500] 17.3.2.26, with these
|
|
322
|
+
* departures from it, each measured by docx4j:
|
|
323
|
+
*
|
|
324
|
+
* - the Indic, Thai, Lao, Myanmar and Khmer ranges use cs, where the table says hAnsi
|
|
325
|
+
* (docx4j issues 622 and 666);
|
|
326
|
+
* - an East Asian reference is "eastAsia (or eastAsiaTheme) if defined": a run naming none
|
|
327
|
+
* gets hAnsi in those places, never nothing;
|
|
328
|
+
* - characters outside the Basic Multilingual Plane, which the table does not cover: the
|
|
329
|
+
* {@link RunFontSelectorSource.emojiFont} where one is configured, else hAnsi (Word uses
|
|
330
|
+
* Segoe UI Emoji, which docx4j's coverage pass finds).
|
|
331
|
+
*
|
|
332
|
+
* What the table says and Word confirmed: U+0020 is ASCII and takes the ascii font, so the
|
|
333
|
+
* space between two East Asian words is the Latin font's; Hebrew, Arabic and the rest of
|
|
334
|
+
* U+0590-U+07BF in a run with no `w:cs` take the ascii font. The table's other condition for
|
|
335
|
+
* U+0100-U+02AF and U+1E00-U+1EFF under `hint=eastAsia`, "or the character set of the
|
|
336
|
+
* eastAsia font is Chinese5 or GB2312", needs the font's OS/2 code-page bits and is not
|
|
337
|
+
* implemented here either.
|
|
338
|
+
*
|
|
339
|
+
* **U+2190-U+2BFF**: docx4j asks whether the hAnsi font has the glyph and names Segoe UI
|
|
340
|
+
* Symbol where it does not. That is a glyph check over a font file, which this CR does not
|
|
341
|
+
* port (CR-001 section 14.2), so the hAnsi font is answered - which is also docx4j's answer
|
|
342
|
+
* wherever Segoe UI Symbol is not among the fonts it has, the environment the parity goldens
|
|
343
|
+
* record.
|
|
344
|
+
*
|
|
345
|
+
* @returns a document font name; undefined only where the run names no hAnsi font either
|
|
346
|
+
*/
|
|
347
|
+
fontFor(cp, hint, langEastAsia, eastAsia, ascii, hAnsi, cs) {
|
|
348
|
+
// "eastAsia (or eastAsiaTheme if defined)": where the run names none, the table's hAnsi
|
|
349
|
+
const ea = eastAsia !== null && eastAsia !== void 0 ? eastAsia : hAnsi;
|
|
350
|
+
const hintEA = hint === 'eastAsia';
|
|
351
|
+
if (cp > 0xFFFF) {
|
|
352
|
+
if (isEmoji(cp) && this.source.emojiFont !== undefined)
|
|
353
|
+
return this.source.emojiFont;
|
|
354
|
+
return hAnsi;
|
|
355
|
+
}
|
|
356
|
+
const c = cp;
|
|
357
|
+
// Basic Latin: "@ascii is used to format all characters in the ASCII range (0-127)"
|
|
358
|
+
if (c <= 0x7F)
|
|
359
|
+
return ascii;
|
|
360
|
+
// Latin-1 Supplement: hAnsi, with the table's exceptions under hint=eastAsia
|
|
361
|
+
if (c >= 0xA0 && c <= 0xFF) {
|
|
362
|
+
if (hintEA && eastAsia !== undefined) {
|
|
363
|
+
// "If hint is eastAsia, the following characters use eastAsia: A1, A4, A7-A8, AA, AD,
|
|
364
|
+
// AF, B0-B4, B6-BA, BC-BF, D7, F7"
|
|
365
|
+
if (c === 0xA1 || c === 0xA4 || (c >= 0xA7 && c <= 0xA8) || c === 0xAA
|
|
366
|
+
|| c === 0xAD || c === 0xAF || (c >= 0xB0 && c <= 0xB4)
|
|
367
|
+
|| (c >= 0xB6 && c <= 0xBA) || (c >= 0xBC && c <= 0xBF)
|
|
368
|
+
|| c === 0xD7 || c === 0xF7)
|
|
369
|
+
return eastAsia;
|
|
370
|
+
// "If hint is eastAsia and the language of the run is either Chinese Traditional or
|
|
371
|
+
// Chinese Simplified, the following characters use eastAsia: E0-E1, E8-EA, EC-ED,
|
|
372
|
+
// F2-F3, F9-FA, FC"
|
|
373
|
+
if (contains(langEastAsia, 'zh') && ((c >= 0xE0 && c <= 0xE1) || (c >= 0xE8 && c <= 0xEA)
|
|
374
|
+
|| (c >= 0xEC && c <= 0xED) || (c >= 0xF2 && c <= 0xF3)
|
|
375
|
+
|| (c >= 0xF9 && c <= 0xFA) || c === 0xFC))
|
|
376
|
+
return eastAsia;
|
|
377
|
+
}
|
|
378
|
+
return hAnsi;
|
|
379
|
+
}
|
|
380
|
+
// Latin Extended-A, Latin Extended-B, IPA Extensions
|
|
381
|
+
if (c >= 0x100 && c <= 0x2AF)
|
|
382
|
+
return (hintEA && contains(langEastAsia, 'zh')) ? ea : hAnsi;
|
|
383
|
+
// Spacing Modifier Letters .. Cyrillic Supplement
|
|
384
|
+
if (c >= 0x2B0 && c <= 0x4FF)
|
|
385
|
+
return hintEA ? ea : hAnsi;
|
|
386
|
+
// Hebrew, Arabic, Syriac, Thaana, NKo: ascii (measured, fonts-hebrew-no-cs)
|
|
387
|
+
if (c >= 0x590 && c <= 0x7BF)
|
|
388
|
+
return ascii;
|
|
389
|
+
// the Indic scripts, Thai, Lao, Myanmar, Khmer and the Khmer symbols: cs (issues 622, 666)
|
|
390
|
+
if ((c >= 0x900 && c <= 0xDFF) || (c >= 0xE00 && c <= 0xEFF) || (c >= 0x1000 && c <= 0x109F)
|
|
391
|
+
|| (c >= 0x1780 && c <= 0x17FF) || (c >= 0x19E0 && c <= 0x19FF)) {
|
|
392
|
+
return cs !== null && cs !== void 0 ? cs : hAnsi;
|
|
393
|
+
}
|
|
394
|
+
// Hangul Jamo
|
|
395
|
+
if (c >= 0x1100 && c <= 0x11FF)
|
|
396
|
+
return ea;
|
|
397
|
+
// Latin Extended Additional
|
|
398
|
+
if (c >= 0x1E00 && c <= 0x1EFF)
|
|
399
|
+
return (hintEA && contains(langEastAsia, 'zh')) ? ea : hAnsi;
|
|
400
|
+
// General Punctuation .. Number Forms: ordinary text
|
|
401
|
+
if (c >= 0x2000 && c <= 0x218F)
|
|
402
|
+
return hintEA ? ea : hAnsi;
|
|
403
|
+
// the symbol blocks: Arrows .. Braille (docx4j glyph-checks these; see the javadoc above)
|
|
404
|
+
if (c >= 0x2190 && c <= 0x2BFF)
|
|
405
|
+
return hintEA ? ea : hAnsi;
|
|
406
|
+
// Glagolitic .. CJK Radicals Supplement
|
|
407
|
+
if (c >= 0x2C00 && c <= 0x2EFF)
|
|
408
|
+
return hintEA ? ea : hAnsi;
|
|
409
|
+
// the CJK ranges (and the surrogate range, which a paired surrogate never reaches here)
|
|
410
|
+
if (c >= 0x2F00 && c <= 0xDFFF)
|
|
411
|
+
return ea;
|
|
412
|
+
// Private Use Area; F000-F0FF is where the symbol fonts live
|
|
413
|
+
if (c >= 0xE000 && c <= 0xF8FF)
|
|
414
|
+
return hintEA ? ea : hAnsi;
|
|
415
|
+
// CJK Compatibility Ideographs
|
|
416
|
+
if (c >= 0xF900 && c <= 0xFAFF)
|
|
417
|
+
return ea;
|
|
418
|
+
// Alphabetic Presentation Forms: "If the hint is eastAsia then eastAsia is used for
|
|
419
|
+
// FB00-FB1C. For FB1D-FB4F, ascii is used."
|
|
420
|
+
if (c >= 0xFB00 && c <= 0xFB4F) {
|
|
421
|
+
if (c >= 0xFB1D)
|
|
422
|
+
return ascii;
|
|
423
|
+
return hintEA ? ea : hAnsi;
|
|
424
|
+
}
|
|
425
|
+
// Arabic Presentation Forms-A
|
|
426
|
+
if (c >= 0xFB50 && c <= 0xFDFF)
|
|
427
|
+
return ascii;
|
|
428
|
+
// CJK Compatibility Forms, Small Form Variants
|
|
429
|
+
if (c >= 0xFE30 && c <= 0xFE6F)
|
|
430
|
+
return ea;
|
|
431
|
+
// Arabic Presentation Forms-B
|
|
432
|
+
if (c >= 0xFE70 && c <= 0xFEFE)
|
|
433
|
+
return ascii;
|
|
434
|
+
// Halfwidth and Fullwidth Forms
|
|
435
|
+
if (c >= 0xFF00 && c <= 0xFFEF)
|
|
436
|
+
return ea;
|
|
437
|
+
// "for all ranges not listed in the above, the hAnsi font shall be used"
|
|
438
|
+
// (Georgian, Armenian, Ethiopic, Tibetan, Mongolian, Greek Extended, the C1 controls ...)
|
|
439
|
+
return hAnsi;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type * as dml from '@docx4j/generated-objects-ts/modules/org_docx4j_dml';
|
|
2
|
+
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
3
|
+
/** `w:themeFontLang`. */
|
|
4
|
+
export type ThemeFontLang = wml.CTLanguage;
|
|
5
|
+
/** A theme's font scheme, or a whole theme (`a:theme`), or nothing. */
|
|
6
|
+
export type ThemeSource = dml.Theme | dml.BaseStyles.FontScheme | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* The face a theme reference names in this theme, for this `w:themeFontLang`.
|
|
9
|
+
*
|
|
10
|
+
* With no `w:themeFontLang` (or none that applies to this reference), the collection's own
|
|
11
|
+
* `a:latin` / `a:ea` / `a:cs`. With one, the language's script (`Jpan`, `Hans`, `Geor` ...)
|
|
12
|
+
* picks from the collection's `a:font` list, falling back to the collection's own face where
|
|
13
|
+
* the language selects no script or the list has no entry for it.
|
|
14
|
+
*
|
|
15
|
+
* @returns the typeface, or undefined where the theme answers nothing.
|
|
16
|
+
*/
|
|
17
|
+
export declare function themeFontOf(theme: ThemeSource, type: wml.STTheme | undefined, themeFontLang?: ThemeFontLang | undefined): string | undefined;
|