@openpresentation/opf-render 0.10.0 → 0.11.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 +67 -7
- package/dist/font-compatibility.js +40 -1
- package/dist/font-manifest.js +1285 -12
- package/dist/font-policy.js +91 -36
- package/dist/fonts-browser.d.ts +56 -2
- package/dist/fonts-browser.js +194 -22
- package/dist/fonts-node.d.ts +53 -9
- package/dist/fonts-node.js +121 -23
- package/dist/fonts.d.ts +20 -5
- package/dist/fonts.js +63 -27
- package/dist/index.d.ts +11 -0
- package/dist/lazy-font-list.js +23 -0
- package/dist/lazy-fonts.js +52 -0
- package/dist/raster.js +3 -1
- package/dist/script-font-pack.js +140 -1
- package/dist/script-fonts.js +161 -24
- package/dist/svg.d.ts +11 -0
- package/dist/svg.js +97 -5
- package/fonts/anton/Anton-Regular.ttf +0 -0
- package/fonts/anton/OFL.txt +93 -0
- package/fonts/anton/PROVENANCE.json +21 -0
- package/fonts/archivo-narrow/ArchivoNarrow_400Regular.ttf +0 -0
- package/fonts/archivo-narrow/ArchivoNarrow_400Regular_Italic.ttf +0 -0
- package/fonts/archivo-narrow/ArchivoNarrow_700Bold.ttf +0 -0
- package/fonts/archivo-narrow/ArchivoNarrow_700Bold_Italic.ttf +0 -0
- package/fonts/archivo-narrow/OFL.txt +93 -0
- package/fonts/archivo-narrow/PROVENANCE.json +47 -0
- package/fonts/barlow/Barlow-Bold.ttf +0 -0
- package/fonts/barlow/Barlow-BoldItalic.ttf +0 -0
- package/fonts/barlow/Barlow-Italic.ttf +0 -0
- package/fonts/barlow/Barlow-Regular.ttf +0 -0
- package/fonts/barlow/OFL.txt +93 -0
- package/fonts/barlow/PROVENANCE.json +45 -0
- package/fonts/bebas-neue/BebasNeue_400Regular.ttf +0 -0
- package/fonts/bebas-neue/OFL.txt +93 -0
- package/fonts/bebas-neue/PROVENANCE.json +23 -0
- package/fonts/bitter/Bitter_400Regular.ttf +0 -0
- package/fonts/bitter/Bitter_400Regular_Italic.ttf +0 -0
- package/fonts/bitter/Bitter_700Bold.ttf +0 -0
- package/fonts/bitter/Bitter_700Bold_Italic.ttf +0 -0
- package/fonts/bitter/OFL.txt +94 -0
- package/fonts/bitter/PROVENANCE.json +49 -0
- package/fonts/carlito/Carlito-Bold.ttf +0 -0
- package/fonts/carlito/Carlito-BoldItalic.ttf +0 -0
- package/fonts/carlito/Carlito-Italic.ttf +0 -0
- package/fonts/carlito/Carlito-Regular.ttf +0 -0
- package/fonts/carlito/OFL.txt +94 -0
- package/fonts/eb-garamond/EBGaramond_400Regular.ttf +0 -0
- package/fonts/eb-garamond/EBGaramond_400Regular_Italic.ttf +0 -0
- package/fonts/eb-garamond/EBGaramond_700Bold.ttf +0 -0
- package/fonts/eb-garamond/EBGaramond_700Bold_Italic.ttf +0 -0
- package/fonts/eb-garamond/OFL.txt +93 -0
- package/fonts/eb-garamond/PROVENANCE.json +47 -0
- package/fonts/figtree/Figtree_400Regular.ttf +0 -0
- package/fonts/figtree/Figtree_400Regular_Italic.ttf +0 -0
- package/fonts/figtree/Figtree_700Bold.ttf +0 -0
- package/fonts/figtree/Figtree_700Bold_Italic.ttf +0 -0
- package/fonts/figtree/OFL.txt +93 -0
- package/fonts/figtree/PROVENANCE.json +47 -0
- package/fonts/intos/Intos-Bold.ttf +0 -0
- package/fonts/intos/Intos-BoldItalic.ttf +0 -0
- package/fonts/intos/Intos-Italic.ttf +0 -0
- package/fonts/intos/Intos-Regular.ttf +0 -0
- package/fonts/intos/IntosDisplay-Bold.ttf +0 -0
- package/fonts/intos/IntosDisplay-BoldItalic.ttf +0 -0
- package/fonts/intos/IntosDisplay-Italic.ttf +0 -0
- package/fonts/intos/IntosDisplay-Regular.ttf +0 -0
- package/fonts/intos/IntosNarrow-Bold.ttf +0 -0
- package/fonts/intos/IntosNarrow-BoldItalic.ttf +0 -0
- package/fonts/intos/IntosNarrow-Italic.ttf +0 -0
- package/fonts/intos/IntosNarrow-Regular.ttf +0 -0
- package/fonts/intos/IntosSerif-Bold.ttf +0 -0
- package/fonts/intos/IntosSerif-BoldItalic.ttf +0 -0
- package/fonts/intos/IntosSerif-Italic.ttf +0 -0
- package/fonts/intos/IntosSerif-Regular.ttf +0 -0
- package/fonts/intos/NOTICE.md +18 -0
- package/fonts/intos/OFL.txt +94 -0
- package/fonts/intos/PROVENANCE.json +144 -0
- package/fonts/libre-caslon-text/LibreCaslonText_400Regular.ttf +0 -0
- package/fonts/libre-caslon-text/LibreCaslonText_400Regular_Italic.ttf +0 -0
- package/fonts/libre-caslon-text/LibreCaslonText_700Bold.ttf +0 -0
- package/fonts/libre-caslon-text/OFL.txt +93 -0
- package/fonts/libre-caslon-text/PROVENANCE.json +39 -0
- package/fonts/lora/Lora-Bold.ttf +0 -0
- package/fonts/lora/Lora-BoldItalic.ttf +0 -0
- package/fonts/lora/Lora-Italic.ttf +0 -0
- package/fonts/lora/Lora-Regular.ttf +0 -0
- package/fonts/lora/OFL.txt +93 -0
- package/fonts/lora/PROVENANCE.json +48 -0
- package/fonts/merriweather-sans/MerriweatherSans-Bold.ttf +0 -0
- package/fonts/merriweather-sans/MerriweatherSans-BoldItalic.ttf +0 -0
- package/fonts/merriweather-sans/MerriweatherSans-Italic.ttf +0 -0
- package/fonts/merriweather-sans/MerriweatherSans-Regular.ttf +0 -0
- package/fonts/merriweather-sans/OFL.txt +96 -0
- package/fonts/merriweather-sans/PROVENANCE.json +48 -0
- package/fonts/montserrat/Montserrat_400Regular.ttf +0 -0
- package/fonts/montserrat/Montserrat_400Regular_Italic.ttf +0 -0
- package/fonts/montserrat/Montserrat_700Bold.ttf +0 -0
- package/fonts/montserrat/Montserrat_700Bold_Italic.ttf +0 -0
- package/fonts/montserrat/Montserrat_900Black.ttf +0 -0
- package/fonts/montserrat/OFL.txt +93 -0
- package/fonts/montserrat/PROVENANCE.json +55 -0
- package/fonts/open-sans/OFL.txt +92 -0
- package/fonts/open-sans/OpenSans_400Regular.ttf +0 -0
- package/fonts/open-sans/OpenSans_400Regular_Italic.ttf +0 -0
- package/fonts/open-sans/OpenSans_700Bold.ttf +0 -0
- package/fonts/open-sans/OpenSans_700Bold_Italic.ttf +0 -0
- package/fonts/open-sans/PROVENANCE.json +47 -0
- package/fonts/poppins/OFL.txt +93 -0
- package/fonts/poppins/PROVENANCE.json +47 -0
- package/fonts/poppins/Poppins_400Regular.ttf +0 -0
- package/fonts/poppins/Poppins_400Regular_Italic.ttf +0 -0
- package/fonts/poppins/Poppins_700Bold.ttf +0 -0
- package/fonts/poppins/Poppins_700Bold_Italic.ttf +0 -0
- package/fonts/pt-serif/OFL.txt +93 -0
- package/fonts/pt-serif/PROVENANCE.json +50 -0
- package/fonts/pt-serif/PT_Serif-Web-Bold.ttf +0 -0
- package/fonts/pt-serif/PT_Serif-Web-BoldItalic.ttf +0 -0
- package/fonts/pt-serif/PT_Serif-Web-Italic.ttf +0 -0
- package/fonts/pt-serif/PT_Serif-Web-Regular.ttf +0 -0
- package/fonts/red-hat-display/OFL.txt +93 -0
- package/fonts/red-hat-display/PROVENANCE.json +79 -0
- package/fonts/red-hat-display/RedHatDisplay_300Light.ttf +0 -0
- package/fonts/red-hat-display/RedHatDisplay_300Light_Italic.ttf +0 -0
- package/fonts/red-hat-display/RedHatDisplay_400Regular.ttf +0 -0
- package/fonts/red-hat-display/RedHatDisplay_400Regular_Italic.ttf +0 -0
- package/fonts/red-hat-display/RedHatDisplay_600SemiBold.ttf +0 -0
- package/fonts/red-hat-display/RedHatDisplay_600SemiBold_Italic.ttf +0 -0
- package/fonts/red-hat-display/RedHatDisplay_700Bold.ttf +0 -0
- package/fonts/red-hat-display/RedHatDisplay_700Bold_Italic.ttf +0 -0
- package/fonts/red-hat-text/OFL.txt +93 -0
- package/fonts/red-hat-text/PROVENANCE.json +47 -0
- package/fonts/red-hat-text/RedHatText_400Regular.ttf +0 -0
- package/fonts/red-hat-text/RedHatText_400Regular_Italic.ttf +0 -0
- package/fonts/red-hat-text/RedHatText_700Bold.ttf +0 -0
- package/fonts/red-hat-text/RedHatText_700Bold_Italic.ttf +0 -0
- package/fonts/source-sans-3/OFL.txt +93 -0
- package/fonts/source-sans-3/PROVENANCE.json +49 -0
- package/fonts/source-sans-3/SourceSans3-Bold.ttf +0 -0
- package/fonts/source-sans-3/SourceSans3-BoldIt.ttf +0 -0
- package/fonts/source-sans-3/SourceSans3-It.ttf +0 -0
- package/fonts/source-sans-3/SourceSans3-Regular.ttf +0 -0
- package/fonts/work-sans/OFL.txt +93 -0
- package/fonts/work-sans/PROVENANCE.json +47 -0
- package/fonts/work-sans/WorkSans_400Regular.ttf +0 -0
- package/fonts/work-sans/WorkSans_400Regular_Italic.ttf +0 -0
- package/fonts/work-sans/WorkSans_700Bold.ttf +0 -0
- package/fonts/work-sans/WorkSans_700Bold_Italic.ttf +0 -0
- package/package.json +11 -10
package/dist/font-policy.js
CHANGED
|
@@ -5,9 +5,9 @@ const SNAPSHOT=freeze({
|
|
|
5
5
|
"decisions": {
|
|
6
6
|
"status": "provisional, owner may revise",
|
|
7
7
|
"aptos-preview": {
|
|
8
|
-
"replacement": "
|
|
9
|
-
"compatibility": "
|
|
10
|
-
"note": "
|
|
8
|
+
"replacement": "Intos",
|
|
9
|
+
"compatibility": "metric",
|
|
10
|
+
"note": "Owner policy 2026-09-29: a licensed font the user selects previews with an open replacement that looks similar and has the same size on screen; the PPTX keeps the selected name. Aptos previews with Intos (metric, OFL-1.1, vendored in opf-render); Roboto and Carlito are alternates for registries built without the Intos faces (they are in the opf-render office pack)."
|
|
11
11
|
},
|
|
12
12
|
"segoe-ui-preview": {
|
|
13
13
|
"replacement": "Red Hat Display",
|
|
@@ -23,7 +23,7 @@ const SNAPSHOT=freeze({
|
|
|
23
23
|
},
|
|
24
24
|
"source": {
|
|
25
25
|
"path": "spec/reference/font-policy.json",
|
|
26
|
-
"sha256": "
|
|
26
|
+
"sha256": "2616392b58bcaaffef5182c612ad7b562f9187cd099f919ca3abee225a5411a3"
|
|
27
27
|
},
|
|
28
28
|
"families": [
|
|
29
29
|
{
|
|
@@ -81,18 +81,20 @@ const SNAPSHOT=freeze({
|
|
|
81
81
|
"embeddableByOpf": false,
|
|
82
82
|
"replacement": {
|
|
83
83
|
"decision": "aptos-preview",
|
|
84
|
+
"source": "https://github.com/muglug/intos/tree/fef9315c14da9e4b23b4c3cac8e718998d4e4736",
|
|
84
85
|
"measured": {
|
|
85
|
-
"replacement": "
|
|
86
|
-
"meanAbsWidthDelta": 0
|
|
87
|
-
"meanWidthDelta": 0
|
|
88
|
-
"maxAbsWidthDelta": 0
|
|
86
|
+
"replacement": "Intos",
|
|
87
|
+
"meanAbsWidthDelta": 0,
|
|
88
|
+
"meanWidthDelta": 0,
|
|
89
|
+
"maxAbsWidthDelta": 0,
|
|
89
90
|
"styles": 4,
|
|
90
91
|
"reference": "Aptos 2.01;O365"
|
|
91
92
|
},
|
|
92
|
-
"family": "
|
|
93
|
-
"compatibility": "
|
|
93
|
+
"family": "Intos",
|
|
94
|
+
"compatibility": "metric"
|
|
94
95
|
},
|
|
95
96
|
"alternates": [
|
|
97
|
+
"Roboto",
|
|
96
98
|
"Carlito"
|
|
97
99
|
]
|
|
98
100
|
},
|
|
@@ -105,18 +107,20 @@ const SNAPSHOT=freeze({
|
|
|
105
107
|
],
|
|
106
108
|
"embeddableByOpf": false,
|
|
107
109
|
"replacement": {
|
|
108
|
-
"family": "
|
|
109
|
-
"compatibility": "
|
|
110
|
+
"family": "Intos Display",
|
|
111
|
+
"compatibility": "metric",
|
|
112
|
+
"source": "https://github.com/muglug/intos/tree/fef9315c14da9e4b23b4c3cac8e718998d4e4736",
|
|
110
113
|
"measured": {
|
|
111
|
-
"replacement": "
|
|
112
|
-
"meanAbsWidthDelta": 0
|
|
113
|
-
"meanWidthDelta":
|
|
114
|
-
"maxAbsWidthDelta": 0
|
|
114
|
+
"replacement": "Intos Display",
|
|
115
|
+
"meanAbsWidthDelta": 0,
|
|
116
|
+
"meanWidthDelta": 0,
|
|
117
|
+
"maxAbsWidthDelta": 0,
|
|
115
118
|
"styles": 4,
|
|
116
119
|
"reference": "Aptos Display 2.01;O365"
|
|
117
120
|
}
|
|
118
121
|
},
|
|
119
122
|
"alternates": [
|
|
123
|
+
"Carlito",
|
|
120
124
|
"Roboto"
|
|
121
125
|
]
|
|
122
126
|
},
|
|
@@ -146,17 +150,21 @@ const SNAPSHOT=freeze({
|
|
|
146
150
|
],
|
|
147
151
|
"embeddableByOpf": false,
|
|
148
152
|
"replacement": {
|
|
149
|
-
"family": "
|
|
150
|
-
"compatibility": "
|
|
153
|
+
"family": "Intos Narrow",
|
|
154
|
+
"compatibility": "metric",
|
|
155
|
+
"source": "https://github.com/muglug/intos/tree/fef9315c14da9e4b23b4c3cac8e718998d4e4736",
|
|
151
156
|
"measured": {
|
|
152
|
-
"replacement": "
|
|
153
|
-
"meanAbsWidthDelta": 0
|
|
154
|
-
"meanWidthDelta": 0
|
|
155
|
-
"maxAbsWidthDelta": 0
|
|
157
|
+
"replacement": "Intos Narrow",
|
|
158
|
+
"meanAbsWidthDelta": 0,
|
|
159
|
+
"meanWidthDelta": 0,
|
|
160
|
+
"maxAbsWidthDelta": 0,
|
|
156
161
|
"styles": 4,
|
|
157
162
|
"reference": "Aptos Narrow 2.01;O365"
|
|
158
163
|
}
|
|
159
|
-
}
|
|
164
|
+
},
|
|
165
|
+
"alternates": [
|
|
166
|
+
"Carlito"
|
|
167
|
+
]
|
|
160
168
|
},
|
|
161
169
|
{
|
|
162
170
|
"family": "Aptos Serif",
|
|
@@ -167,10 +175,21 @@ const SNAPSHOT=freeze({
|
|
|
167
175
|
],
|
|
168
176
|
"embeddableByOpf": false,
|
|
169
177
|
"replacement": {
|
|
170
|
-
"family": "
|
|
171
|
-
"compatibility": "
|
|
172
|
-
"
|
|
173
|
-
|
|
178
|
+
"family": "Intos Serif",
|
|
179
|
+
"compatibility": "metric",
|
|
180
|
+
"source": "https://github.com/muglug/intos/tree/fef9315c14da9e4b23b4c3cac8e718998d4e4736",
|
|
181
|
+
"measured": {
|
|
182
|
+
"replacement": "Intos Serif",
|
|
183
|
+
"meanAbsWidthDelta": 0,
|
|
184
|
+
"meanWidthDelta": 0,
|
|
185
|
+
"maxAbsWidthDelta": 0,
|
|
186
|
+
"styles": 4,
|
|
187
|
+
"reference": "Aptos Serif 2.01;240513210638;O365"
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
"alternates": [
|
|
191
|
+
"Tinos"
|
|
192
|
+
]
|
|
174
193
|
},
|
|
175
194
|
{
|
|
176
195
|
"family": "Arabic Typesetting",
|
|
@@ -675,8 +694,8 @@ const SNAPSHOT=freeze({
|
|
|
675
694
|
"compatibility": "visual",
|
|
676
695
|
"measured": {
|
|
677
696
|
"replacement": "Source Sans 3",
|
|
678
|
-
"meanAbsWidthDelta": 0.
|
|
679
|
-
"meanWidthDelta": 0.
|
|
697
|
+
"meanAbsWidthDelta": 0.0158,
|
|
698
|
+
"meanWidthDelta": 0.0152,
|
|
680
699
|
"maxAbsWidthDelta": 0.0521,
|
|
681
700
|
"styles": 4,
|
|
682
701
|
"reference": "Corbel 6.01"
|
|
@@ -957,12 +976,16 @@ const SNAPSHOT=freeze({
|
|
|
957
976
|
"embeddableByOpf": false,
|
|
958
977
|
"replacement": {
|
|
959
978
|
"family": "Gelasio",
|
|
960
|
-
"compatibility": "
|
|
979
|
+
"compatibility": "metric",
|
|
980
|
+
"disabledFeatures": [
|
|
981
|
+
"liga",
|
|
982
|
+
"clig"
|
|
983
|
+
],
|
|
961
984
|
"measured": {
|
|
962
985
|
"replacement": "Gelasio",
|
|
963
|
-
"meanAbsWidthDelta": 0
|
|
964
|
-
"meanWidthDelta":
|
|
965
|
-
"maxAbsWidthDelta": 0
|
|
986
|
+
"meanAbsWidthDelta": 0,
|
|
987
|
+
"meanWidthDelta": 0,
|
|
988
|
+
"maxAbsWidthDelta": 0,
|
|
966
989
|
"styles": 4,
|
|
967
990
|
"reference": "Georgia 5.59"
|
|
968
991
|
},
|
|
@@ -982,9 +1005,9 @@ const SNAPSHOT=freeze({
|
|
|
982
1005
|
"compatibility": "visual",
|
|
983
1006
|
"measured": {
|
|
984
1007
|
"replacement": "Source Sans 3",
|
|
985
|
-
"meanAbsWidthDelta": 0.
|
|
986
|
-
"meanWidthDelta": 0.
|
|
987
|
-
"maxAbsWidthDelta": 0.
|
|
1008
|
+
"meanAbsWidthDelta": 0.0511,
|
|
1009
|
+
"meanWidthDelta": 0.0039,
|
|
1010
|
+
"maxAbsWidthDelta": 0.1459,
|
|
988
1011
|
"styles": 4,
|
|
989
1012
|
"reference": "Gill Sans MT 1.65"
|
|
990
1013
|
}
|
|
@@ -1098,6 +1121,38 @@ const SNAPSHOT=freeze({
|
|
|
1098
1121
|
"Carlito"
|
|
1099
1122
|
]
|
|
1100
1123
|
},
|
|
1124
|
+
{
|
|
1125
|
+
"family": "Intos",
|
|
1126
|
+
"licenseClass": "open",
|
|
1127
|
+
"license": "OFL-1.1",
|
|
1128
|
+
"availability": [],
|
|
1129
|
+
"embeddableByOpf": true,
|
|
1130
|
+
"replacement": null
|
|
1131
|
+
},
|
|
1132
|
+
{
|
|
1133
|
+
"family": "Intos Display",
|
|
1134
|
+
"licenseClass": "open",
|
|
1135
|
+
"license": "OFL-1.1",
|
|
1136
|
+
"availability": [],
|
|
1137
|
+
"embeddableByOpf": true,
|
|
1138
|
+
"replacement": null
|
|
1139
|
+
},
|
|
1140
|
+
{
|
|
1141
|
+
"family": "Intos Narrow",
|
|
1142
|
+
"licenseClass": "open",
|
|
1143
|
+
"license": "OFL-1.1",
|
|
1144
|
+
"availability": [],
|
|
1145
|
+
"embeddableByOpf": true,
|
|
1146
|
+
"replacement": null
|
|
1147
|
+
},
|
|
1148
|
+
{
|
|
1149
|
+
"family": "Intos Serif",
|
|
1150
|
+
"licenseClass": "open",
|
|
1151
|
+
"license": "OFL-1.1",
|
|
1152
|
+
"availability": [],
|
|
1153
|
+
"embeddableByOpf": true,
|
|
1154
|
+
"replacement": null
|
|
1155
|
+
},
|
|
1101
1156
|
{
|
|
1102
1157
|
"family": "Kalinga",
|
|
1103
1158
|
"licenseClass": "proprietary-standard",
|
package/dist/fonts-browser.d.ts
CHANGED
|
@@ -3,13 +3,48 @@ import type {
|
|
|
3
3
|
FontRegistry,
|
|
4
4
|
FontRegistryOptions,
|
|
5
5
|
} from "./fonts.js";
|
|
6
|
-
import type { BundledFontPackage, ScriptSelection } from "./fonts-node.js";
|
|
6
|
+
import type { AutoScriptSelection, BundledFontPackage, LazyFont, ScriptSelection } from "./fonts-node.js";
|
|
7
|
+
export type { LazyFont } from "./fonts-node.js";
|
|
8
|
+
export type { AutoScriptSelection } from "./fonts-node.js";
|
|
9
|
+
export { detectPresentationScripts, autoScriptSelection } from "./fonts-node.js";
|
|
7
10
|
export interface BrowserFontInput extends Omit<FontFaceInput, "data"> {
|
|
8
11
|
data?: Uint8Array;
|
|
9
12
|
url?: string;
|
|
10
13
|
/** Reviewed SHA-256 (hex); verified with Web Crypto before the face is used. */
|
|
11
14
|
sha256?: string;
|
|
12
15
|
}
|
|
16
|
+
export interface BrowserFontRegistry extends FontRegistry {
|
|
17
|
+
dispose(): void;
|
|
18
|
+
/** Every vendored face a host can load on demand: family, style, package-relative file and pinned sha256. */
|
|
19
|
+
readonly lazyFonts: readonly LazyFont[];
|
|
20
|
+
/**
|
|
21
|
+
* Load the vendored faces (for example Intos for the default Aptos scheme) the presentation's font families resolve to
|
|
22
|
+
* under the registry's `substitutionPolicy` (nothing is downloaded for a family the policy would not resolve), once
|
|
23
|
+
* each, from `lazyFontsBaseUrl`. Fetches and verifies every file, then adds the faces to the document and the registry
|
|
24
|
+
* together; on failure nothing changes and the call can be retried. Call it before measuring a document. After
|
|
25
|
+
* `dispose()` it rejects with `font-registry-disposed`.
|
|
26
|
+
*/
|
|
27
|
+
ensureLazyFonts(presentation: unknown, options?: { signal?: AbortSignal }): Promise<LazyFont[]>;
|
|
28
|
+
/** Synchronous: the vendored faces the presentation needs under the registry's policy that are not loaded yet. Empty means `ensureLazyFonts` fetches nothing. */
|
|
29
|
+
pendingLazyFonts(presentation: unknown): LazyFont[];
|
|
30
|
+
|
|
31
|
+
/** Load script faces for ISO 15924 codes (or "all") from `scriptBaseUrl`. Resolves with the newly loaded package names. */
|
|
32
|
+
loadScripts(scripts: ScriptSelection, options?: { signal?: AbortSignal }): Promise<string[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Load the script faces the presentation's text needs, once each (FF-19). Cheap when nothing new is
|
|
35
|
+
* needed. Also loads the CJK face a glyph fallback needs for drawn characters the loaded faces lack. Call it after
|
|
36
|
+
* edits and render again afterwards: measurements planned earlier do not know the new faces. `signal` belongs to
|
|
37
|
+
* this call only. `uncovered` lists drawn CJK characters no loaded face covers. At most one CJK face beyond the text's own
|
|
38
|
+
* scripts is loaded for glyph fallback. If a package fails the others still load and the call rejects with an
|
|
39
|
+
* OPFFontError whose `details` are `{ loaded: string[]; failed: {package, code, message}[] }`. A failed call (fetch, hash, FontFace load) leaves nothing loaded and can be retried; after
|
|
40
|
+
* `dispose()` it rejects with `font-registry-disposed`.
|
|
41
|
+
*/
|
|
42
|
+
ensureScripts(presentation: unknown, options?: { signal?: AbortSignal }): Promise<AutoScriptSelection & { loaded: string[]; uncovered: string[] }>;
|
|
43
|
+
/** Synchronous: package names the presentation needs that are not loaded yet. Empty means `ensureScripts` fetches nothing, so a host can render immediately. */
|
|
44
|
+
pendingScripts(presentation: unknown): string[];
|
|
45
|
+
/** Names of the script-pack packages loaded so far. */
|
|
46
|
+
readonly loadedScriptPackages: string[];
|
|
47
|
+
}
|
|
13
48
|
export declare function loadBrowserFontRegistry(
|
|
14
49
|
entries: BrowserFontInput[],
|
|
15
50
|
options?: FontRegistryOptions & {
|
|
@@ -17,11 +52,30 @@ export declare function loadBrowserFontRegistry(
|
|
|
17
52
|
fetch?: typeof fetch;
|
|
18
53
|
signal?: AbortSignal;
|
|
19
54
|
crypto?: { subtle: SubtleCrypto };
|
|
55
|
+
/** Script faces to load once the registry exists: "auto" (with `presentation`), "all" or ISO 15924 codes. Needs `scriptBaseUrl`. */
|
|
56
|
+
scripts?: ScriptSelection | "auto";
|
|
57
|
+
/** The presentation whose text decides `scripts: "auto"`. */
|
|
58
|
+
presentation?: unknown;
|
|
59
|
+
/** Where the host serves the installed `@expo-google-fonts/*` packages; script faces are fetched from here, hash-verified. */
|
|
60
|
+
scriptBaseUrl?: string;
|
|
61
|
+
/** Where the host serves this package's `fonts` directory, so vendored faces (Intos, the open families) load on demand from `<base>/<package-relative file>` (fonts/intos/..., fonts/<family>/...). */
|
|
62
|
+
lazyFontsBaseUrl?: string;
|
|
20
63
|
},
|
|
21
|
-
): Promise<
|
|
64
|
+
): Promise<BrowserFontRegistry>;
|
|
22
65
|
export declare function scriptFontPackages(scripts: ScriptSelection): BundledFontPackage[];
|
|
23
66
|
/** Hash-pinned browser entries for the script pack, served by the host from `baseUrl`. */
|
|
24
67
|
export declare function scriptFontEntries(
|
|
25
68
|
scripts: ScriptSelection,
|
|
26
69
|
options: { baseUrl: string },
|
|
27
70
|
): (BrowserFontInput & { url: string; family: string; weight: number; italic: boolean; sha256: string; scripts: string[]; package: string; license: string })[];
|
|
71
|
+
/** Every vendored face of this package: family, style, package-relative file, sha256. */
|
|
72
|
+
export declare function lazyFontList(): readonly LazyFont[];
|
|
73
|
+
/** Hash-pinned browser entries for the vendored faces, served by the host from `baseUrl` at their package-relative paths. */
|
|
74
|
+
export declare function lazyFontEntries(options: { baseUrl: string }, list?: readonly LazyFont[]): (BrowserFontInput & { url: string; family: string; weight: number; italic: boolean; sha256: string; package: string })[];
|
|
75
|
+
/** The font families a presentation's slides resolve (heading, body and code roles); empty for a document that does not resolve. */
|
|
76
|
+
export declare function presentationFamilies(presentation: unknown): Set<string>;
|
|
77
|
+
/**
|
|
78
|
+
* The vendored faces a set of resolved families needs that the registry does not hold, following the registry's own order and
|
|
79
|
+
* `policy` (default "visual"): the family itself, an alias target, the declared replacement, then its alternates.
|
|
80
|
+
*/
|
|
81
|
+
export declare function lazyFontsFor(families: Iterable<string>, context: { lazy: readonly LazyFont[]; hasFamily(family: string): boolean; loaded?: ReadonlySet<string>; policy?: "none" | "metric" | "visual"; aliases?: ReadonlyMap<string, string> }): LazyFont[];
|
package/dist/fonts-browser.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { createFontRegistry, OPFFontError } from "./fonts.js";
|
|
2
|
-
|
|
2
|
+
import { lazyFontEntries, lazyFontList } from "./lazy-font-list.js";
|
|
3
|
+
import { lazyFontsFor, presentationFamilies } from "./lazy-fonts.js";
|
|
4
|
+
import { analyzePresentationScripts, nextFallbackPackage, scriptFontPackages, scriptPackageEntries, scriptSelectionOf, uncoveredCjkCharacters } from "./script-font-pack.js";
|
|
5
|
+
export { autoScriptSelection, detectPresentationScripts, scriptFontEntries, scriptFontPackages } from "./script-font-pack.js";
|
|
6
|
+
export { lazyFontEntries, lazyFontList } from "./lazy-font-list.js";
|
|
7
|
+
export { lazyFontsFor, presentationFamilies } from "./lazy-fonts.js";
|
|
3
8
|
|
|
4
9
|
async function verifyDigest(entry, data, subtle) {
|
|
5
10
|
if (entry.sha256 === undefined) return;
|
|
@@ -26,8 +31,8 @@ export async function loadBrowserFontRegistry(entries, options = {}) {
|
|
|
26
31
|
);
|
|
27
32
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
28
33
|
const subtle = options.crypto?.subtle ?? globalThis.crypto?.subtle;
|
|
29
|
-
const
|
|
30
|
-
|
|
34
|
+
const fetchFaces = (list, signal) => Promise.all(
|
|
35
|
+
list.map(async (entry) => {
|
|
31
36
|
let loaded = entry;
|
|
32
37
|
if (!entry.data) {
|
|
33
38
|
if (!entry.url)
|
|
@@ -35,7 +40,7 @@ export async function loadBrowserFontRegistry(entries, options = {}) {
|
|
|
35
40
|
"invalid-font-source",
|
|
36
41
|
"Supply font bytes or a font-file URL.",
|
|
37
42
|
);
|
|
38
|
-
const response = await fetcher(entry.url, { signal
|
|
43
|
+
const response = await fetcher(entry.url, { signal });
|
|
39
44
|
if (!response.ok)
|
|
40
45
|
throw new OPFFontError(
|
|
41
46
|
"font-fetch-failed",
|
|
@@ -49,34 +54,201 @@ export async function loadBrowserFontRegistry(entries, options = {}) {
|
|
|
49
54
|
return loaded;
|
|
50
55
|
}),
|
|
51
56
|
);
|
|
57
|
+
const faces = await fetchFaces(entries, options.signal);
|
|
52
58
|
const registry = createFontRegistry(faces, options),
|
|
53
59
|
loaded = [];
|
|
54
60
|
// Normalize family names using the registry's parsed font metadata.
|
|
55
61
|
const described = registry.describeFaces();
|
|
62
|
+
// Registers browser FontFaces for faces already parsed by the registry; on failure nothing stays registered.
|
|
63
|
+
const registerBrowserFaces = async (list, descriptors) => {
|
|
64
|
+
const added = [];
|
|
65
|
+
try {
|
|
66
|
+
await Promise.all(
|
|
67
|
+
list.map(async (entry, index) => {
|
|
68
|
+
const descriptor = descriptors[index];
|
|
69
|
+
const face = new FontFaceRef(
|
|
70
|
+
descriptor.family,
|
|
71
|
+
entry.data.slice().buffer,
|
|
72
|
+
{
|
|
73
|
+
weight: String(descriptor.weight),
|
|
74
|
+
style: descriptor.italic ? "italic" : "normal",
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
await face.load();
|
|
78
|
+
added.push(face);
|
|
79
|
+
}),
|
|
80
|
+
);
|
|
81
|
+
for (const face of added) documentRef.fonts.add(face);
|
|
82
|
+
await documentRef.fonts.ready;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
for (const face of added) documentRef.fonts.delete(face);
|
|
85
|
+
throw new OPFFontError("font-load-failed", error.message);
|
|
86
|
+
}
|
|
87
|
+
loaded.push(...added);
|
|
88
|
+
};
|
|
89
|
+
await registerBrowserFaces(faces, described);
|
|
90
|
+
|
|
91
|
+
// Script faces (FF-19) are loaded lazily, once a document needs them, and only for the scripts it uses.
|
|
92
|
+
const scriptPackages = new Set();
|
|
93
|
+
let queue = Promise.resolve(), disposed = false;
|
|
94
|
+
const gone = () => new OPFFontError("font-registry-disposed", "The font registry was disposed.");
|
|
95
|
+
const baseUrl = () => {
|
|
96
|
+
if (typeof options.scriptBaseUrl !== "string" || !options.scriptBaseUrl)
|
|
97
|
+
throw new OPFFontError("invalid-font-source", "Loading script fonts requires scriptBaseUrl, where the host serves the installed @expo-google-fonts packages.");
|
|
98
|
+
return options.scriptBaseUrl;
|
|
99
|
+
};
|
|
100
|
+
// Loads whole packages. Order matters: fetch and verify, load every FontFace (not yet visible to the document),
|
|
101
|
+
// then register them with the document and add them to the registry atomically. Nothing is half loaded: on any
|
|
102
|
+
// failure (fetch, hash, FontFace.load, registry) the document and registry are unchanged and the packages stay
|
|
103
|
+
// pending, so the next call retries. `signal` belongs to this call only.
|
|
104
|
+
const loadPackageList = (packages, { signal } = {}) => {
|
|
105
|
+
const result = queue.then(async () => {
|
|
106
|
+
if (disposed) throw gone();
|
|
107
|
+
signal?.throwIfAborted?.();
|
|
108
|
+
const pending = packages.filter((item) => !scriptPackages.has(item.name));
|
|
109
|
+
if (!pending.length) return [];
|
|
110
|
+
const fetched = await fetchFaces(scriptPackageEntries(pending, { baseUrl: baseUrl() }), signal);
|
|
111
|
+
let browserFaces;
|
|
112
|
+
try {
|
|
113
|
+
browserFaces = await Promise.all(fetched.map(async (entry) => {
|
|
114
|
+
const face = new FontFaceRef(entry.family, entry.data.slice().buffer, { weight: String(entry.weight ?? 400), style: entry.italic ? "italic" : "normal" });
|
|
115
|
+
await face.load();
|
|
116
|
+
return face;
|
|
117
|
+
}));
|
|
118
|
+
} catch (error) { throw new OPFFontError("font-load-failed", error.message); }
|
|
119
|
+
if (disposed) throw gone();
|
|
120
|
+
const shown = [];
|
|
121
|
+
try {
|
|
122
|
+
for (const face of browserFaces) { documentRef.fonts.add(face); shown.push(face); }
|
|
123
|
+
registry.addFaces(fetched);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
for (const face of shown) documentRef.fonts.delete(face);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
loaded.push(...browserFaces);
|
|
129
|
+
for (const item of pending) scriptPackages.add(item.name);
|
|
130
|
+
try { await documentRef.fonts.ready; } catch { /* the faces are loaded and registered */ }
|
|
131
|
+
return pending.map((item) => item.name);
|
|
132
|
+
});
|
|
133
|
+
queue = result.catch(() => {});
|
|
134
|
+
return result;
|
|
135
|
+
};
|
|
136
|
+
const covers = (character) => registry.scriptFacesCover(character);
|
|
137
|
+
Object.assign(registry, {
|
|
138
|
+
/** Load the script faces for explicit ISO 15924 codes (or 'all'). Resolves with the newly loaded package names. `signal` aborts this call's fetches. */
|
|
139
|
+
loadScripts: (scripts, callOptions) => loadPackageList(scriptFontPackages(scripts), callOptions),
|
|
140
|
+
/**
|
|
141
|
+
* Load the script faces the presentation's text needs, once each (FF-19), then the (at most one) CJK face a glyph
|
|
142
|
+
* fallback needs for characters the loaded faces lack. Cheap when nothing new is needed; call it after edits and
|
|
143
|
+
* render again afterwards. Resolves with the detected scripts, the packages loaded by this call, the scripts no
|
|
144
|
+
* pinned font serves and `uncovered`, drawn CJK characters no loaded face covers (the renderer reports
|
|
145
|
+
* `missing-glyph` for them). Each package loads all or nothing. If some package fails, the others still load: the
|
|
146
|
+
* call then rejects with an OPFFontError (the first failure's code) whose `details` hold `loaded` (packages this
|
|
147
|
+
* call did load) and `failed` (`{package, code, message}` per failed package); nothing is lost and a later call
|
|
148
|
+
* retries only the failures. `signal` aborts this call's fetches.
|
|
149
|
+
*/
|
|
150
|
+
async ensureScripts(presentation, callOptions) {
|
|
151
|
+
if (disposed) throw gone();
|
|
152
|
+
const analysis = analyzePresentationScripts(presentation), selection = scriptSelectionOf(analysis);
|
|
153
|
+
const loadedNow = [], failed = [];
|
|
154
|
+
const attempt = async (item) => {
|
|
155
|
+
try { loadedNow.push(...(await loadPackageList([item], callOptions))); }
|
|
156
|
+
catch (error) { failed.push({ package: item.name, code: error?.code ?? "font-load-failed", message: error?.message ?? String(error), error }); }
|
|
157
|
+
};
|
|
158
|
+
for (const item of scriptFontPackages(selection.scripts)) await attempt(item);
|
|
159
|
+
// Fallback faces only follow a clean primary load: a failed package would otherwise be judged uncovered.
|
|
160
|
+
if (!failed.length) for (let next = nextFallbackPackage(analysis, { covers, loaded: scriptPackages }); next && !failed.length; next = nextFallbackPackage(analysis, { covers, loaded: scriptPackages })) await attempt(next);
|
|
161
|
+
// An aborted call rejects with the signal's reason; packages loaded before the abort stay loaded.
|
|
162
|
+
if (callOptions?.signal?.aborted) throw callOptions.signal.reason ?? failed[0]?.error;
|
|
163
|
+
if (failed.length) {
|
|
164
|
+
const first = failed[0];
|
|
165
|
+
throw new OPFFontError(first.code, first.message, { loaded: loadedNow, failed: failed.map(({ package: name, code, message }) => ({ package: name, code, message })), cause: first.error });
|
|
166
|
+
}
|
|
167
|
+
return { ...selection, loaded: loadedNow, uncovered: uncoveredCjkCharacters(analysis, { covers }) };
|
|
168
|
+
},
|
|
169
|
+
/** Synchronous: script-pack packages the presentation needs that are not loaded yet. Empty means `ensureScripts` would fetch nothing. */
|
|
170
|
+
pendingScripts(presentation) {
|
|
171
|
+
const analysis = analyzePresentationScripts(presentation);
|
|
172
|
+
const primary = scriptFontPackages(scriptSelectionOf(analysis).scripts).map((item) => item.name).filter((name) => !scriptPackages.has(name));
|
|
173
|
+
if (primary.length) return primary;
|
|
174
|
+
const next = nextFallbackPackage(analysis, { covers, loaded: scriptPackages });
|
|
175
|
+
return next ? [next.name] : [];
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
// FF-31: vendored faces (the open families and Intos) load on demand, once a document needs them. They share the
|
|
179
|
+
// script loader's queue and disposed state, and the same all-or-nothing order: fetch and verify, load every FontFace,
|
|
180
|
+
// then add them to the document and the registry together.
|
|
181
|
+
const lazy = lazyFontList(), lazyLoaded = new Set();
|
|
182
|
+
const policy = options.substitutionPolicy ?? "none";
|
|
183
|
+
const aliasTargets = new Map(Object.entries(options.aliases ?? {}).map(([from, to]) => [from.toLowerCase(), to]));
|
|
184
|
+
const hasFamily = (family) => registry.describeFaces().some((face) => face.family.toLowerCase() === String(family).toLowerCase());
|
|
185
|
+
const neededLazy = (presentation) => lazyFontsFor(presentationFamilies(presentation), { lazy, hasFamily, loaded: lazyLoaded, policy, aliases: aliasTargets });
|
|
186
|
+
const lazyBaseUrl = () => {
|
|
187
|
+
if (typeof options.lazyFontsBaseUrl !== "string" || !options.lazyFontsBaseUrl)
|
|
188
|
+
throw new OPFFontError("invalid-font-source", "Loading vendored fonts requires lazyFontsBaseUrl, where the host serves the package's fonts directory.");
|
|
189
|
+
return options.lazyFontsBaseUrl;
|
|
190
|
+
};
|
|
191
|
+
Object.assign(registry, {
|
|
192
|
+
/** Every vendored face a host can load on demand: family, style, package-relative file and pinned sha256. */
|
|
193
|
+
lazyFonts: lazy,
|
|
194
|
+
/**
|
|
195
|
+
* Load the vendored faces the presentation's font families resolve to under the registry's substitution policy (nothing
|
|
196
|
+
* is downloaded for a family the policy would not resolve), once each. All or nothing: on any failure (fetch, hash,
|
|
197
|
+
* FontFace.load, registry) the document and registry are unchanged and the call can be retried. Cheap when nothing is
|
|
198
|
+
* needed. Call it before measuring a document, and again after edits that change fonts. Resolves with the faces added.
|
|
199
|
+
*/
|
|
200
|
+
ensureLazyFonts(presentation, callOptions = {}) {
|
|
201
|
+
const result = queue.then(async () => {
|
|
202
|
+
if (disposed) throw gone();
|
|
203
|
+
callOptions.signal?.throwIfAborted?.();
|
|
204
|
+
const pending = neededLazy(presentation);
|
|
205
|
+
if (!pending.length) return [];
|
|
206
|
+
const fetched = (await fetchFaces(lazyFontEntries({ baseUrl: lazyBaseUrl() }, pending), callOptions.signal)).map((entry) => ({ ...entry, embed: "used" }));
|
|
207
|
+
let browserFaces;
|
|
208
|
+
try {
|
|
209
|
+
browserFaces = await Promise.all(fetched.map(async (entry) => {
|
|
210
|
+
const face = new FontFaceRef(entry.family, entry.data.slice().buffer, { weight: String(entry.weight), style: entry.italic ? "italic" : "normal" });
|
|
211
|
+
await face.load();
|
|
212
|
+
return face;
|
|
213
|
+
}));
|
|
214
|
+
} catch (error) { throw new OPFFontError("font-load-failed", error.message); }
|
|
215
|
+
if (disposed) throw gone();
|
|
216
|
+
const shown = [];
|
|
217
|
+
try {
|
|
218
|
+
for (const face of browserFaces) { documentRef.fonts.add(face); shown.push(face); }
|
|
219
|
+
registry.addFaces(fetched);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
for (const face of shown) documentRef.fonts.delete(face);
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
loaded.push(...browserFaces);
|
|
225
|
+
for (const item of pending) lazyLoaded.add(item.file);
|
|
226
|
+
try { await documentRef.fonts.ready; } catch { /* the faces are loaded and registered */ }
|
|
227
|
+
return pending;
|
|
228
|
+
});
|
|
229
|
+
queue = result.catch(() => {});
|
|
230
|
+
return result;
|
|
231
|
+
},
|
|
232
|
+
/** Synchronous: the vendored faces the presentation needs under the registry's policy that are not loaded yet. Empty means `ensureLazyFonts` fetches nothing. */
|
|
233
|
+
pendingLazyFonts: (presentation) => neededLazy(presentation),
|
|
234
|
+
});
|
|
235
|
+
/** Names of the script-pack packages loaded so far. */
|
|
236
|
+
Object.defineProperty(registry, "loadedScriptPackages", { get: () => [...scriptPackages], enumerable: true });
|
|
56
237
|
try {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
weight: String(descriptor.weight),
|
|
65
|
-
style: descriptor.italic ? "italic" : "normal",
|
|
66
|
-
},
|
|
67
|
-
);
|
|
68
|
-
await face.load();
|
|
69
|
-
loaded.push(face);
|
|
70
|
-
}),
|
|
71
|
-
);
|
|
72
|
-
for (const face of loaded) documentRef.fonts.add(face);
|
|
73
|
-
await documentRef.fonts.ready;
|
|
238
|
+
if (options.scripts === "auto") {
|
|
239
|
+
if (options.presentation === null || typeof options.presentation !== "object")
|
|
240
|
+
throw new OPFFontError("invalid-font-scripts", "scripts: 'auto' needs the presentation whose text decides the scripts.", { scripts: options.scripts });
|
|
241
|
+
await registry.ensureScripts(options.presentation, { signal: options.signal });
|
|
242
|
+
} else if (options.scripts !== undefined && !(Array.isArray(options.scripts) && !options.scripts.length)) {
|
|
243
|
+
await registry.loadScripts(options.scripts, { signal: options.signal });
|
|
244
|
+
}
|
|
74
245
|
} catch (error) {
|
|
75
246
|
for (const face of loaded) documentRef.fonts.delete(face);
|
|
76
|
-
throw
|
|
247
|
+
throw error;
|
|
77
248
|
}
|
|
78
249
|
return Object.assign(registry, {
|
|
79
250
|
dispose() {
|
|
251
|
+
disposed = true;
|
|
80
252
|
for (const face of loaded) documentRef.fonts.delete(face);
|
|
81
253
|
},
|
|
82
254
|
});
|
package/dist/fonts-node.d.ts
CHANGED
|
@@ -1,24 +1,68 @@
|
|
|
1
|
-
import type {FontRegistry,FontRegistryOptions,EmbeddedFont,FontFaceInput} from "./fonts.js";
|
|
1
|
+
import type {FontRegistry,FontRegistryOptions,EmbeddedFont,FontFaceInput,ScriptFontProfile} from "./fonts.js";
|
|
2
2
|
/** A caller-supplied face (FF-31), for example a licensed copy of the real font. Node callers may pass a file path. */
|
|
3
3
|
export type CallerFontFace = FontFaceInput | (Omit<FontFaceInput, "data"> & {path: string});
|
|
4
4
|
/** "all" or ISO 15924 codes (`Jpan`, `Hans`, `Hant`, `Kore`, `Arab`, `Hebr`, `Deva`, `Thai`, ...). */
|
|
5
5
|
export type ScriptSelection = "all" | string[];
|
|
6
|
+
/** What `scripts: "auto"` chose for a presentation (FF-19). */
|
|
7
|
+
export interface AutoScriptSelection {
|
|
8
|
+
/** Scripts the presentation's drawn text uses, other than Latin, Greek and Cyrillic. */
|
|
9
|
+
detected: string[];
|
|
10
|
+
/** The detected scripts a pinned package serves; the input for `scriptFontPackages`. */
|
|
11
|
+
scripts: string[];
|
|
12
|
+
/** Detected scripts no pinned open font serves; that text uses the design font. */
|
|
13
|
+
unavailable: string[];
|
|
14
|
+
}
|
|
15
|
+
/** Script-pack packages that `scripts: "auto"` loaded or found not installed. */
|
|
16
|
+
export interface AppliedScriptSelection extends AutoScriptSelection { packages: string[]; notInstalled: string[]; /** Drawn CJK characters no loaded face covers (glyph fallback stopped at its cap). */ uncovered?: string[] }
|
|
17
|
+
/** Script keys whose faces a preview of the presentation needs: text decides, the document language only tells Han scripts apart. */
|
|
18
|
+
export declare function detectPresentationScripts(presentation: unknown, options?: { profile?: ScriptFontProfile }): string[];
|
|
19
|
+
export declare function autoScriptSelection(presentation: unknown, options?: { profile?: ScriptFontProfile }): AutoScriptSelection;
|
|
6
20
|
export interface ScriptPackOptions {
|
|
7
21
|
/** Caller-supplied faces, loaded first so a licensed real font resolves as an exact face (FF-31). */
|
|
8
22
|
faces?: readonly CallerFontFace[];
|
|
9
|
-
/**
|
|
10
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Also load the optional, hash-pinned OFL Noto script pack for these scripts (FF-19).
|
|
25
|
+
* `"auto"` loads only the scripts `presentation` draws (and needs it); a script package that is not installed
|
|
26
|
+
* is reported through `onDiagnostic` instead of failing.
|
|
27
|
+
*/
|
|
28
|
+
scripts?: ScriptSelection | "auto";
|
|
29
|
+
/** The presentation whose text decides `scripts: "auto"`. */
|
|
30
|
+
presentation?: unknown;
|
|
31
|
+
/** Receives `script-font-unavailable` and `script-font-not-installed` for `scripts: "auto"`. */
|
|
32
|
+
onDiagnostic?: (diagnostic: {code: string; message: string; script?: string; package?: string; scripts?: string[]}) => void;
|
|
11
33
|
}
|
|
12
|
-
|
|
34
|
+
/** A vendored face that an SVG embeds only when its text names the family (the open families and Intos), and that browser hosts load on demand from a separate hash-pinned file. */
|
|
35
|
+
export interface LazyFont { readonly package: string; readonly family: string; readonly weight: number; readonly italic: boolean; /** Path relative to the package root, for example fonts/intos/Intos-Regular.ttf. */ readonly file: string; readonly sha256: string; readonly license: string; readonly renamedFrom?: string }
|
|
36
|
+
export type ScriptFontRegistry = FontRegistry & {fontFiles:string[]; /** Set for `scripts: "auto"`. */ scriptSelection?: AppliedScriptSelection};
|
|
37
|
+
export type NodeFontRegistry = ScriptFontRegistry & {/** The embed "used" faces this registry holds, with the files a host copies to serve them itself. */ lazyFonts: readonly LazyFont[]};
|
|
38
|
+
export declare function loadBundledFontRegistry(options?: FontRegistryOptions & ScriptPackOptions): Promise<NodeFontRegistry>;
|
|
13
39
|
|
|
14
|
-
export declare function loadOfficeFontRegistry(options?: FontRegistryOptions & ScriptPackOptions & {includeBaseFonts?:boolean}): Promise<
|
|
40
|
+
export declare function loadOfficeFontRegistry(options?: FontRegistryOptions & ScriptPackOptions & {includeBaseFonts?:boolean; /** Leave out the open families font schemes select (FF-31); default true. */ includeOpenFonts?:boolean}): Promise<NodeFontRegistry>;
|
|
15
41
|
|
|
16
42
|
export type BundledFontPackage = Readonly<{
|
|
17
|
-
name
|
|
43
|
+
/** An npm package name, or a plain id for a vendored entry of a git upstream. */
|
|
44
|
+
name:string;
|
|
45
|
+
/** The exact npm version, or for a git-upstream vendored entry the pinned upstream commit. */
|
|
46
|
+
version:string; pack:"base"|"office"|"open"|"scripts"; source:string;
|
|
47
|
+
/** FF-31: directory inside this package (for example `fonts/carlito`) that holds the vendored faces and notice (`file` and `licenseFile` are relative to it); absent for npm packages. */
|
|
48
|
+
vendored?: string;
|
|
49
|
+
/** "used": the package's faces are embedded in an SVG only when its text names the family, and browsers load them on demand (the open pack always does). */
|
|
50
|
+
embed?: "used";
|
|
51
|
+
/** An authored provenance and copyright notice in `vendored`, hash-pinned beside the license and appended to it. */
|
|
52
|
+
noticeFile?: string; noticeSha256?: string;
|
|
18
53
|
/** ISO 15924 scripts served by a script-pack package. */
|
|
19
54
|
scripts?: readonly string[];
|
|
20
55
|
license:string; licenseFile:string; licenseSha256:string;
|
|
21
|
-
|
|
56
|
+
/** Vendored from a git upstream: the commit-pinned URL of the notice. Vendored from npm: the notice's path in the npm package. */
|
|
57
|
+
upstreamLicenseUrl?:string; npmLicenseFile?:string;
|
|
58
|
+
/** The family this package is the renamed successor of; requests for the old name draw these faces, reported visual. */
|
|
59
|
+
renamedFrom?:string;
|
|
60
|
+
reservedFontNames:readonly string[]; upstream:string; copyright:string;
|
|
61
|
+
faces:readonly Readonly<{file:string; family:string; weight:number; italic:boolean; sha256:string;
|
|
62
|
+
/** FF-31: the byte-identical upstream release file this face is (sha256 equals the face's own). */
|
|
63
|
+
upstreamFile?: Readonly<{url:string; sha256:string}>;
|
|
64
|
+
/** FF-31: for a vendored npm-derived (instanced) face, its path in the npm package it was copied from. */
|
|
65
|
+
npmFile?: string}>[];
|
|
22
66
|
}>;
|
|
23
67
|
export interface BundledFontManifest {
|
|
24
68
|
readonly version: number;
|
|
@@ -27,7 +71,7 @@ export interface BundledFontManifest {
|
|
|
27
71
|
export declare const BUNDLED_FONT_MANIFEST: BundledFontManifest;
|
|
28
72
|
export declare function scriptFontPackages(scripts: ScriptSelection): BundledFontPackage[];
|
|
29
73
|
export interface PreparedNodeFonts {
|
|
30
|
-
registry:
|
|
74
|
+
registry: NodeFontRegistry;
|
|
31
75
|
manifest: BundledFontManifest;
|
|
32
76
|
options: {
|
|
33
77
|
textMeasurement: FontRegistry["textMeasurement"];
|
|
@@ -37,4 +81,4 @@ export interface PreparedNodeFonts {
|
|
|
37
81
|
loadSystemFonts: false;
|
|
38
82
|
};
|
|
39
83
|
}
|
|
40
|
-
export declare function prepareNodeFonts(options?: FontRegistryOptions & ScriptPackOptions & {pack?:"base"|"office"; includeBaseFonts?:boolean; /** Embed script faces in SVG (large); default false. */ embedScriptFonts?:boolean}): Promise<PreparedNodeFonts>;
|
|
84
|
+
export declare function prepareNodeFonts(options?: FontRegistryOptions & ScriptPackOptions & {pack?:"base"|"office"; includeBaseFonts?:boolean; /** With pack "office": leave out the open families (FF-31); default true. */ includeOpenFonts?:boolean; /** Embed script faces in SVG (large); default false. */ embedScriptFonts?:boolean;}): Promise<PreparedNodeFonts>;
|