@superdoc-dev/mcp 0.11.0-next.3 → 0.11.0-next.5

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.
Files changed (2) hide show
  1. package/dist/index.js +1157 -721
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -219498,7 +219498,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
219498
219498
  init_remark_gfm_BhnWr3yf_es();
219499
219499
  });
219500
219500
 
219501
- // ../../packages/superdoc/dist/chunks/src-CF4og_LY.es.js
219501
+ // ../../packages/superdoc/dist/chunks/src-DvgAvHbj.es.js
219502
219502
  function deleteProps(obj, propOrProps) {
219503
219503
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
219504
219504
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -259643,6 +259643,221 @@ function computeTabWidth(currentPos, justification, tabs, hangingIndent, firstLi
259643
259643
  tabWidth = nextDefaultTabStop - currentPos;
259644
259644
  return tabWidth;
259645
259645
  }
259646
+ function isSettled(status) {
259647
+ return SETTLED_STATUSES.includes(status);
259648
+ }
259649
+ function normalizeFamilyKey$2(family$1) {
259650
+ return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
259651
+ }
259652
+ function splitStack(cssFontFamily) {
259653
+ return cssFontFamily.split(",").map((part) => part.trim()).filter(Boolean);
259654
+ }
259655
+ function createFontResolver() {
259656
+ return new FontResolver;
259657
+ }
259658
+ function resolveFontFamily2(logicalFamily) {
259659
+ return defaultResolver.resolveFontFamily(logicalFamily);
259660
+ }
259661
+ function resolvePhysicalFamily(cssFontFamily) {
259662
+ return defaultResolver.resolvePhysicalFamily(cssFontFamily);
259663
+ }
259664
+ function resolveFace(logicalFamily, face, hasFace) {
259665
+ return defaultResolver.resolveFace(logicalFamily, face, hasFace);
259666
+ }
259667
+ function getFontConfigVersion() {
259668
+ return fontConfigVersion;
259669
+ }
259670
+ function bumpFontConfigVersion() {
259671
+ return fontConfigVersion += 1;
259672
+ }
259673
+ function fourFaces(filePrefix) {
259674
+ return [
259675
+ {
259676
+ weight: "normal",
259677
+ style: "normal",
259678
+ file: `${filePrefix}-Regular.woff2`
259679
+ },
259680
+ {
259681
+ weight: "bold",
259682
+ style: "normal",
259683
+ file: `${filePrefix}-Bold.woff2`
259684
+ },
259685
+ {
259686
+ weight: "normal",
259687
+ style: "italic",
259688
+ file: `${filePrefix}-Italic.woff2`
259689
+ },
259690
+ {
259691
+ weight: "bold",
259692
+ style: "italic",
259693
+ file: `${filePrefix}-BoldItalic.woff2`
259694
+ }
259695
+ ];
259696
+ }
259697
+ function family(name, filePrefix, license) {
259698
+ return {
259699
+ family: name,
259700
+ license,
259701
+ faces: fourFaces(filePrefix)
259702
+ };
259703
+ }
259704
+ function withTrailingSlash(base4) {
259705
+ return base4.endsWith("/") ? base4 : `${base4}/`;
259706
+ }
259707
+ function joinUrl(base4, file2) {
259708
+ return `${withTrailingSlash(base4)}${file2}`;
259709
+ }
259710
+ function weightToken(weight) {
259711
+ return weight === "bold" ? "700" : "400";
259712
+ }
259713
+ function bundledAssetSignature(resolve2) {
259714
+ const family$1 = BUNDLED_MANIFEST[0];
259715
+ const face = family$1?.faces[0];
259716
+ if (!family$1 || !face)
259717
+ return "";
259718
+ return resolve2({
259719
+ file: face.file,
259720
+ family: family$1.family,
259721
+ weight: weightToken(face.weight),
259722
+ style: face.style,
259723
+ source: "bundled-substitute"
259724
+ });
259725
+ }
259726
+ function installBundledSubstitutes(registry3, options = {}) {
259727
+ const resolve2 = options.resolveAssetUrl ?? ((context) => joinUrl(options.assetBaseUrl ?? defaultAssetBase, context.file));
259728
+ const signature = bundledAssetSignature(resolve2);
259729
+ const installed = installedRegistries.get(registry3);
259730
+ if (installed !== undefined) {
259731
+ if (installed !== signature)
259732
+ console.warn(`[superdoc] bundled fonts are already registered for this document from "${installed}"; a later fonts config resolving to "${signature}" is ignored. Use one fonts.assetBaseUrl / fonts.resolveAssetUrl per document.`);
259733
+ return;
259734
+ }
259735
+ installedRegistries.set(registry3, signature);
259736
+ for (const family$1 of BUNDLED_MANIFEST)
259737
+ for (const face of family$1.faces) {
259738
+ const context = {
259739
+ file: face.file,
259740
+ family: family$1.family,
259741
+ weight: weightToken(face.weight),
259742
+ style: face.style,
259743
+ source: "bundled-substitute"
259744
+ };
259745
+ registry3.register({
259746
+ family: family$1.family,
259747
+ source: `url(${resolve2(context)})`,
259748
+ descriptors: {
259749
+ weight: face.weight,
259750
+ style: face.style
259751
+ }
259752
+ });
259753
+ }
259754
+ }
259755
+ function buildFontReport(logicalFamilies, registry3, resolver2) {
259756
+ const seen = /* @__PURE__ */ new Set;
259757
+ const report = [];
259758
+ for (const logical of logicalFamilies) {
259759
+ if (!logical || seen.has(logical))
259760
+ continue;
259761
+ seen.add(logical);
259762
+ const { physicalFamily, reason } = resolver2 ? resolver2.resolveFontFamily(logical) : resolveFontFamily2(logical);
259763
+ const loadStatus = registry3.getStatus(physicalFamily);
259764
+ report.push({
259765
+ logicalFamily: logical,
259766
+ physicalFamily,
259767
+ reason,
259768
+ loadStatus,
259769
+ exportFamily: logical,
259770
+ missing: isSettled(loadStatus) && loadStatus !== "loaded"
259771
+ });
259772
+ }
259773
+ return report;
259774
+ }
259775
+ function buildFaceReport(usedFaces, registry3, resolver2) {
259776
+ const hasFace = (family$1, weight, style2) => registry3.hasFace(family$1, weight, style2);
259777
+ const seen = /* @__PURE__ */ new Set;
259778
+ const report = [];
259779
+ for (const { logicalFamily, weight, style: style2 } of usedFaces) {
259780
+ if (!logicalFamily)
259781
+ continue;
259782
+ const key2 = `${logicalFamily.toLowerCase()}|${weight}|${style2}`;
259783
+ if (seen.has(key2))
259784
+ continue;
259785
+ seen.add(key2);
259786
+ const face = {
259787
+ weight,
259788
+ style: style2
259789
+ };
259790
+ const { physicalFamily, reason } = resolver2 ? resolver2.resolveFace(logicalFamily, face, hasFace) : resolveFace(logicalFamily, face, hasFace);
259791
+ const loadStatus = registry3.getFaceStatus({
259792
+ family: physicalFamily,
259793
+ weight,
259794
+ style: style2
259795
+ });
259796
+ const missing = reason === "fallback_face_absent" || isSettled(loadStatus) && loadStatus !== "loaded";
259797
+ report.push({
259798
+ logicalFamily,
259799
+ physicalFamily,
259800
+ reason,
259801
+ loadStatus,
259802
+ exportFamily: logicalFamily,
259803
+ missing,
259804
+ face
259805
+ });
259806
+ }
259807
+ return report;
259808
+ }
259809
+ function quoteFamily(family$1) {
259810
+ return `"${family$1.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
259811
+ }
259812
+ function canonicalizeFontSource(source) {
259813
+ const match$1 = /^\s*url\(\s*([\s\S]*?)\s*\)\s*$/i.exec(source);
259814
+ if (!match$1)
259815
+ return source;
259816
+ let inner = match$1[1].trim();
259817
+ if (inner.startsWith('"') && inner.endsWith('"') || inner.startsWith("'") && inner.endsWith("'"))
259818
+ inner = inner.slice(1, -1);
259819
+ return `url(${JSON.stringify(inner)})`;
259820
+ }
259821
+ function normalizeFamilyKey$1(family$1) {
259822
+ return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
259823
+ }
259824
+ function normalizeWeight(weight) {
259825
+ if (weight === undefined)
259826
+ return "400";
259827
+ const w = String(weight).trim().toLowerCase();
259828
+ if (w === "bold" || w === "bolder")
259829
+ return "700";
259830
+ const n = Number(w);
259831
+ return Number.isFinite(n) && n >= 600 ? "700" : "400";
259832
+ }
259833
+ function normalizeStyle$1(style2) {
259834
+ if (!style2)
259835
+ return "normal";
259836
+ const s2 = style2.trim().toLowerCase();
259837
+ return s2.startsWith("italic") || s2.startsWith("oblique") ? "italic" : "normal";
259838
+ }
259839
+ function faceKeyOf$1(family$1, weight, style2) {
259840
+ return `${normalizeFamilyKey$1(family$1)}|${weight}|${style2}`;
259841
+ }
259842
+ function faceProbe(family$1, weight, style2, size$1) {
259843
+ return `${style2 === "italic" ? "italic " : ""}${weight} ${size$1} ${quoteFamily(family$1)}`;
259844
+ }
259845
+ function getFontRegistryFor(fontSet, FontFaceCtor) {
259846
+ if (!fontSet) {
259847
+ if (!domlessRegistry)
259848
+ domlessRegistry = new FontRegistry({});
259849
+ return domlessRegistry;
259850
+ }
259851
+ let registry3 = registriesByFontSet.get(fontSet);
259852
+ if (!registry3) {
259853
+ registry3 = new FontRegistry({
259854
+ fontSet,
259855
+ FontFaceCtor
259856
+ });
259857
+ registriesByFontSet.set(fontSet, registry3);
259858
+ }
259859
+ return registry3;
259860
+ }
259646
259861
  function isResolvedFragmentWithBorders(item) {
259647
259862
  return item !== undefined && item.kind === "fragment" && "paragraphBorders" in item && item.paragraphBorders !== undefined;
259648
259863
  }
@@ -259852,178 +260067,6 @@ function renderPartialEmbeddedTable(params$1) {
259852
260067
  hasSdtContainerChrome: tableResult.hasSdtContainerChrome
259853
260068
  };
259854
260069
  }
259855
- function isSettled(status) {
259856
- return SETTLED_STATUSES.includes(status);
259857
- }
259858
- function normalizeFamilyKey$2(family$1) {
259859
- return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
259860
- }
259861
- function splitStack(cssFontFamily) {
259862
- return cssFontFamily.split(",").map((part) => part.trim()).filter(Boolean);
259863
- }
259864
- function createFontResolver() {
259865
- return new FontResolver;
259866
- }
259867
- function resolveFontFamily2(logicalFamily) {
259868
- return defaultResolver.resolveFontFamily(logicalFamily);
259869
- }
259870
- function resolvePhysicalFamily(cssFontFamily) {
259871
- return defaultResolver.resolvePhysicalFamily(cssFontFamily);
259872
- }
259873
- function resolvePrimaryPhysicalFamily(family$1) {
259874
- return defaultResolver.resolvePrimaryPhysicalFamily(family$1);
259875
- }
259876
- function getFontConfigVersion() {
259877
- return fontConfigVersion;
259878
- }
259879
- function bumpFontConfigVersion() {
259880
- return fontConfigVersion += 1;
259881
- }
259882
- function fourFaces(filePrefix) {
259883
- return [
259884
- {
259885
- weight: "normal",
259886
- style: "normal",
259887
- file: `${filePrefix}-Regular.woff2`
259888
- },
259889
- {
259890
- weight: "bold",
259891
- style: "normal",
259892
- file: `${filePrefix}-Bold.woff2`
259893
- },
259894
- {
259895
- weight: "normal",
259896
- style: "italic",
259897
- file: `${filePrefix}-Italic.woff2`
259898
- },
259899
- {
259900
- weight: "bold",
259901
- style: "italic",
259902
- file: `${filePrefix}-BoldItalic.woff2`
259903
- }
259904
- ];
259905
- }
259906
- function family(name, filePrefix, license) {
259907
- return {
259908
- family: name,
259909
- license,
259910
- faces: fourFaces(filePrefix)
259911
- };
259912
- }
259913
- function withTrailingSlash(base4) {
259914
- return base4.endsWith("/") ? base4 : `${base4}/`;
259915
- }
259916
- function joinUrl(base4, file2) {
259917
- return `${withTrailingSlash(base4)}${file2}`;
259918
- }
259919
- function weightToken(weight) {
259920
- return weight === "bold" ? "700" : "400";
259921
- }
259922
- function bundledAssetSignature(resolve2) {
259923
- const family$1 = BUNDLED_MANIFEST[0];
259924
- const face = family$1?.faces[0];
259925
- if (!family$1 || !face)
259926
- return "";
259927
- return resolve2({
259928
- file: face.file,
259929
- family: family$1.family,
259930
- weight: weightToken(face.weight),
259931
- style: face.style,
259932
- source: "bundled-substitute"
259933
- });
259934
- }
259935
- function installBundledSubstitutes(registry3, options = {}) {
259936
- const resolve2 = options.resolveAssetUrl ?? ((context) => joinUrl(options.assetBaseUrl ?? defaultAssetBase, context.file));
259937
- const signature = bundledAssetSignature(resolve2);
259938
- const installed = installedRegistries.get(registry3);
259939
- if (installed !== undefined) {
259940
- if (installed !== signature)
259941
- console.warn(`[superdoc] bundled fonts are already registered for this document from "${installed}"; a later fonts config resolving to "${signature}" is ignored. Use one fonts.assetBaseUrl / fonts.resolveAssetUrl per document.`);
259942
- return;
259943
- }
259944
- installedRegistries.set(registry3, signature);
259945
- for (const family$1 of BUNDLED_MANIFEST)
259946
- for (const face of family$1.faces) {
259947
- const context = {
259948
- file: face.file,
259949
- family: family$1.family,
259950
- weight: weightToken(face.weight),
259951
- style: face.style,
259952
- source: "bundled-substitute"
259953
- };
259954
- registry3.register({
259955
- family: family$1.family,
259956
- source: `url(${resolve2(context)})`,
259957
- descriptors: {
259958
- weight: face.weight,
259959
- style: face.style
259960
- }
259961
- });
259962
- }
259963
- }
259964
- function buildFontReport(logicalFamilies, registry3, resolver2) {
259965
- const seen = /* @__PURE__ */ new Set;
259966
- const report = [];
259967
- for (const logical of logicalFamilies) {
259968
- if (!logical || seen.has(logical))
259969
- continue;
259970
- seen.add(logical);
259971
- const { physicalFamily, reason } = resolver2 ? resolver2.resolveFontFamily(logical) : resolveFontFamily2(logical);
259972
- const loadStatus = registry3.getStatus(physicalFamily);
259973
- report.push({
259974
- logicalFamily: logical,
259975
- physicalFamily,
259976
- reason,
259977
- loadStatus,
259978
- exportFamily: logical,
259979
- missing: isSettled(loadStatus) && loadStatus !== "loaded"
259980
- });
259981
- }
259982
- return report;
259983
- }
259984
- function quoteFamily(family$1) {
259985
- return `"${family$1.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
259986
- }
259987
- function normalizeFamilyKey$1(family$1) {
259988
- return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
259989
- }
259990
- function normalizeWeight(weight) {
259991
- if (weight === undefined)
259992
- return "400";
259993
- const w = String(weight).trim().toLowerCase();
259994
- if (w === "bold" || w === "bolder")
259995
- return "700";
259996
- const n = Number(w);
259997
- return Number.isFinite(n) && n >= 600 ? "700" : "400";
259998
- }
259999
- function normalizeStyle$1(style2) {
260000
- if (!style2)
260001
- return "normal";
260002
- const s2 = style2.trim().toLowerCase();
260003
- return s2.startsWith("italic") || s2.startsWith("oblique") ? "italic" : "normal";
260004
- }
260005
- function faceKeyOf$1(family$1, weight, style2) {
260006
- return `${normalizeFamilyKey$1(family$1)}|${weight}|${style2}`;
260007
- }
260008
- function faceProbe(family$1, weight, style2, size$1) {
260009
- return `${style2 === "italic" ? "italic " : ""}${weight} ${size$1} ${quoteFamily(family$1)}`;
260010
- }
260011
- function getFontRegistryFor(fontSet, FontFaceCtor) {
260012
- if (!fontSet) {
260013
- if (!domlessRegistry)
260014
- domlessRegistry = new FontRegistry({});
260015
- return domlessRegistry;
260016
- }
260017
- let registry3 = registriesByFontSet.get(fontSet);
260018
- if (!registry3) {
260019
- registry3 = new FontRegistry({
260020
- fontSet,
260021
- FontFaceCtor
260022
- });
260023
- registriesByFontSet.set(fontSet, registry3);
260024
- }
260025
- return registry3;
260026
- }
260027
260070
  function isDigit(ch) {
260028
260071
  return ch >= "0" && ch <= "9";
260029
260072
  }
@@ -267650,7 +267693,7 @@ function invalidateHeaderFooterCache(cache$2, cacheState, headerBlocks, footerBl
267650
267693
  }
267651
267694
  }
267652
267695
  async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, options, measureBlock$1, headerFooter, previousMeasures, fontRuntime) {
267653
- const fontSignature = fontRuntime?.fontSignature ?? "";
267696
+ const fontSignature = fontRuntime?.fontContext?.fontSignature ?? "";
267654
267697
  const previousFontSignature = fontRuntime?.previousFontSignature ?? "";
267655
267698
  const isSemanticFlow = options.flowMode === "semantic";
267656
267699
  if (isSemanticFlow) {
@@ -267871,7 +267914,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
267871
267914
  measureCache.invalidate(Array.from(tokenResult.affectedBlockIds));
267872
267915
  const remeasureStart = performance.now();
267873
267916
  const currentPerSectionConstraints = computePerSectionConstraints(options, currentBlocks);
267874
- currentMeasures = await remeasureAffectedBlocks(currentBlocks, currentMeasures, tokenResult.affectedBlockIds, currentPerSectionConstraints, measureBlock$1, measureCache);
267917
+ currentMeasures = await remeasureAffectedBlocks(currentBlocks, currentMeasures, tokenResult.affectedBlockIds, currentPerSectionConstraints, measureBlock$1, fontSignature, measureCache);
267875
267918
  const remeasureTime = performance.now() - remeasureStart;
267876
267919
  totalRemeasureTime += remeasureTime;
267877
267920
  perfLog$1(`[Perf] 4.3.${iteration + 1}.1 Re-measure: ${remeasureTime.toFixed(2)}ms`);
@@ -269189,7 +269232,7 @@ function buildNumberingContext(layout, sections, blockById, chapterContextCache)
269189
269232
  }))
269190
269233
  };
269191
269234
  }
269192
- async function remeasureAffectedBlocks(blocks2, measures, affectedBlockIds, perBlockConstraints, measureBlock$1, measureCache$1) {
269235
+ async function remeasureAffectedBlocks(blocks2, measures, affectedBlockIds, perBlockConstraints, measureBlock$1, fontSignature, measureCache$1) {
269193
269236
  const updatedMeasures = [...measures];
269194
269237
  for (let i4 = 0;i4 < blocks2.length; i4++) {
269195
269238
  const block = blocks2[i4];
@@ -269199,7 +269242,7 @@ async function remeasureAffectedBlocks(blocks2, measures, affectedBlockIds, perB
269199
269242
  const newMeasure = await measureBlock$1(block, perBlockConstraints[i4]);
269200
269243
  updatedMeasures[i4] = newMeasure;
269201
269244
  const blockConstraints = perBlockConstraints[i4];
269202
- measureCache$1?.set(block, blockConstraints.maxWidth, blockConstraints.maxHeight, newMeasure);
269245
+ measureCache$1?.set(block, blockConstraints.maxWidth, blockConstraints.maxHeight, newMeasure, fontSignature);
269203
269246
  } catch (error48) {
269204
269247
  console.warn(`[incrementalLayout] Failed to re-measure block ${block.id} after token resolution:`, error48);
269205
269248
  }
@@ -275031,8 +275074,10 @@ function clearTableAutoFitMeasurementCaches() {
275031
275074
  autoFitTableResultCache.clear();
275032
275075
  }
275033
275076
  function buildTableCellContentMetricsCacheKey(cell2, options) {
275077
+ const fontContext = options.fontContext ?? DEFAULT_FONT_MEASURE_CONTEXT;
275034
275078
  return stableSerialize({
275035
275079
  maxWidth: Math.max(1, Math.round(options.maxWidth)),
275080
+ fontSignature: fontContext.fontSignature ?? "",
275036
275081
  layoutEpoch: options.layoutEpoch ?? null,
275037
275082
  attrs: cell2.attrs ?? null,
275038
275083
  paragraph: cell2.paragraph ?? null,
@@ -275046,6 +275091,7 @@ function buildAutoFitTableResultCacheKey(table2, options) {
275046
275091
  columnWidths: table2.columnWidths ?? null,
275047
275092
  rowCount: table2.rows.length,
275048
275093
  maxWidth: Math.max(1, Math.round(options.maxWidth)),
275094
+ fontSignature: options.fontSignature ?? "",
275049
275095
  layoutEpoch: options.layoutEpoch ?? null,
275050
275096
  cellMetricKeys: options.cellMetricKeys,
275051
275097
  workingGrid: {
@@ -275085,7 +275131,12 @@ function setCachedAutoFitTableResult(cacheKey, result) {
275085
275131
  autoFitTableResultCache.set(cacheKey, result);
275086
275132
  }
275087
275133
  async function measureTableCellContentMetrics(cell2, options) {
275088
- const cacheKey = buildTableCellContentMetricsCacheKey(cell2, options);
275134
+ const fontContext = options.fontContext ?? DEFAULT_FONT_MEASURE_CONTEXT;
275135
+ const normalizedOptions = {
275136
+ ...options,
275137
+ fontContext
275138
+ };
275139
+ const cacheKey = buildTableCellContentMetricsCacheKey(cell2, normalizedOptions);
275089
275140
  const cached2 = tableCellMetricsCache.get(cacheKey);
275090
275141
  if (cached2)
275091
275142
  return cached2;
@@ -275102,7 +275153,7 @@ async function measureTableCellContentMetrics(cell2, options) {
275102
275153
  let minContentWidthPx = 0;
275103
275154
  let maxContentWidthPx = 0;
275104
275155
  for (const block of contentBlocks) {
275105
- const metrics = await measureIntrinsicBlockWidthMetrics(block, options);
275156
+ const metrics = await measureIntrinsicBlockWidthMetrics(block, normalizedOptions);
275106
275157
  minContentWidthPx = Math.max(minContentWidthPx, metrics.minWidthPx);
275107
275158
  maxContentWidthPx = Math.max(maxContentWidthPx, metrics.maxWidthPx);
275108
275159
  }
@@ -275113,7 +275164,7 @@ async function measureTableCellContentMetrics(cell2, options) {
275113
275164
  tableCellMetricsCache.set(cacheKey, result);
275114
275165
  return result;
275115
275166
  }
275116
- async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayout, measureBlock$1) {
275167
+ async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayout, measureBlock$1, fontContext = DEFAULT_FONT_MEASURE_CONTEXT) {
275117
275168
  const tableMeasurementBasis = Math.max(1, fixedLayout.totalWidth);
275118
275169
  const cellMetricKeys = [];
275119
275170
  const rowMetrics = await Promise.all(table2.rows.map(async (row2, rowIndex) => {
@@ -275124,10 +275175,14 @@ async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayo
275124
275175
  const normalizedCell = normalizedRow.cells?.[cellIndex];
275125
275176
  const span = normalizedCell?.span ?? cell2.colSpan ?? 1;
275126
275177
  const measurementMaxWidth = resolveAutoFitCellMeasurementMaxWidth(cell2, normalizedCell, span, fixedLayout, tableMeasurementBasis, workingInput.gridColumnCount);
275127
- cellMetricKeys.push(buildTableCellContentMetricsCacheKey(cell2, { maxWidth: measurementMaxWidth }));
275178
+ cellMetricKeys.push(buildTableCellContentMetricsCacheKey(cell2, {
275179
+ maxWidth: measurementMaxWidth,
275180
+ fontContext
275181
+ }));
275128
275182
  const metrics = await measureTableCellContentMetrics(cell2, {
275129
275183
  maxWidth: measurementMaxWidth,
275130
- measureBlock: measureBlock$1
275184
+ measureBlock: measureBlock$1,
275185
+ fontContext
275131
275186
  });
275132
275187
  return {
275133
275188
  cellIndex,
@@ -275159,7 +275214,7 @@ async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayo
275159
275214
  }
275160
275215
  async function measureIntrinsicBlockWidthMetrics(block, options) {
275161
275216
  if (block.kind === "paragraph")
275162
- return measureParagraphIntrinsicWidthMetrics(block, options.measureBlock);
275217
+ return measureParagraphIntrinsicWidthMetrics(block, options.measureBlock, options.fontContext);
275163
275218
  if (block.kind === "table")
275164
275219
  return measureNestedTableIntrinsicWidthMetrics(block, options);
275165
275220
  const intrinsicWidth = getIntrinsicAtomicBlockWidth(block);
@@ -275168,13 +275223,13 @@ async function measureIntrinsicBlockWidthMetrics(block, options) {
275168
275223
  maxWidthPx: intrinsicWidth
275169
275224
  };
275170
275225
  }
275171
- async function measureParagraphIntrinsicWidthMetrics(paragraph2, measureBlock$1) {
275226
+ async function measureParagraphIntrinsicWidthMetrics(paragraph2, measureBlock$1, fontContext) {
275172
275227
  const maxLineWidth = (await measureBlock$1(paragraph2, {
275173
275228
  maxWidth: NO_WRAP_MAX_WIDTH,
275174
275229
  maxHeight: Infinity
275175
275230
  })).lines.reduce((widest, line) => Math.max(widest, line.width), 0);
275176
275231
  return {
275177
- minWidthPx: measureParagraphMinTokenWidth(paragraph2),
275232
+ minWidthPx: measureParagraphMinTokenWidth(paragraph2, fontContext),
275178
275233
  maxWidthPx: maxLineWidth
275179
275234
  };
275180
275235
  }
@@ -275193,7 +275248,7 @@ async function measureNestedTableIntrinsicWidthMetrics(table2, options) {
275193
275248
  maxWidthPx: nestedMeasure.totalWidth
275194
275249
  };
275195
275250
  }
275196
- function measureParagraphMinTokenWidth(paragraph2) {
275251
+ function measureParagraphMinTokenWidth(paragraph2, fontContext) {
275197
275252
  let widestToken = 0;
275198
275253
  let currentTokenWidth = 0;
275199
275254
  const flushToken = () => {
@@ -275208,7 +275263,7 @@ function measureParagraphMinTokenWidth(paragraph2) {
275208
275263
  if (isTextLikeRun(run2)) {
275209
275264
  accumulateTextRunMinTokenWidth(run2, (width) => {
275210
275265
  currentTokenWidth += width;
275211
- }, flushToken);
275266
+ }, flushToken, fontContext);
275212
275267
  continue;
275213
275268
  }
275214
275269
  flushToken();
@@ -275217,7 +275272,7 @@ function measureParagraphMinTokenWidth(paragraph2) {
275217
275272
  continue;
275218
275273
  }
275219
275274
  if (run2.kind === "fieldAnnotation") {
275220
- widestToken = Math.max(widestToken, measureFieldAnnotationWidth(run2));
275275
+ widestToken = Math.max(widestToken, measureFieldAnnotationWidth(run2, fontContext));
275221
275276
  continue;
275222
275277
  }
275223
275278
  if (run2.kind === "math")
@@ -275226,8 +275281,8 @@ function measureParagraphMinTokenWidth(paragraph2) {
275226
275281
  flushToken();
275227
275282
  return widestToken;
275228
275283
  }
275229
- function accumulateTextRunMinTokenWidth(run2, appendTokenPiece, flushToken) {
275230
- const font = buildFontString$1(run2);
275284
+ function accumulateTextRunMinTokenWidth(run2, appendTokenPiece, flushToken, fontContext) {
275285
+ const font = buildFontString$1(run2, fontContext);
275231
275286
  let cursor = 0;
275232
275287
  for (const boundary of run2.text.matchAll(TOKEN_BOUNDARY_PATTERN)) {
275233
275288
  const boundaryStart = boundary.index ?? cursor;
@@ -275293,14 +275348,19 @@ function getCanvasContext$1() {
275293
275348
  }
275294
275349
  return canvasContext$1;
275295
275350
  }
275296
- function buildFontString$1(run2) {
275351
+ function buildFontString$1(run2, fontContext) {
275297
275352
  const parts = [];
275298
275353
  if (run2.italic)
275299
275354
  parts.push("italic");
275300
275355
  if (run2.bold)
275301
275356
  parts.push("bold");
275302
275357
  parts.push(`${normalizeFontSize$1(run2.fontSize)}px`);
275303
- parts.push(toCssFontFamily(normalizeFontFamily$1(run2.fontFamily)) ?? normalizeFontFamily$1(run2.fontFamily));
275358
+ const face = {
275359
+ weight: run2.bold ? "700" : "400",
275360
+ style: run2.italic ? "italic" : "normal"
275361
+ };
275362
+ const physicalFamily = normalizeFontFamily$1(fontContext.resolvePhysical(normalizeFontFamily$1(run2.fontFamily), face));
275363
+ parts.push(toCssFontFamily(physicalFamily) ?? physicalFamily);
275304
275364
  return parts.join(" ");
275305
275365
  }
275306
275366
  function applyTextTransform$1(text5, run2, startOffset = 0) {
@@ -275325,14 +275385,14 @@ function capitalizeText$1(text5, fullText, startOffset) {
275325
275385
  }
275326
275386
  return result;
275327
275387
  }
275328
- function measureFieldAnnotationWidth(run2) {
275388
+ function measureFieldAnnotationWidth(run2, fontContext) {
275329
275389
  const fontSize = typeof run2.fontSize === "number" ? run2.fontSize : typeof run2.fontSize === "string" ? parseFloat(run2.fontSize) || DEFAULT_FIELD_ANNOTATION_FONT_SIZE$1 : DEFAULT_FIELD_ANNOTATION_FONT_SIZE$1;
275330
275390
  const font = buildFontString$1({
275331
275391
  fontFamily: normalizeFontFamily$1(run2.fontFamily ?? "Arial"),
275332
275392
  fontSize,
275333
275393
  bold: run2.bold,
275334
275394
  italic: run2.italic
275335
- });
275395
+ }, fontContext);
275336
275396
  return getMeasuredTextWidth(applyTextTransform$1(run2.displayLabel || "", { text: run2.displayLabel || "" }), font, 0, getCanvasContext$1()) + (run2.highlighted === false ? 0 : FIELD_ANNOTATION_PILL_PADDING$1);
275337
275397
  }
275338
275398
  function isExplicitLineBreakRun(run2) {
@@ -275406,14 +275466,20 @@ function getCanvasContext() {
275406
275466
  }
275407
275467
  return canvasContext;
275408
275468
  }
275409
- function buildFontString(run2, resolvePhysical = resolvePhysicalFamily) {
275469
+ function faceOf(run2) {
275470
+ return {
275471
+ weight: run2.bold ? "700" : "400",
275472
+ style: run2.italic ? "italic" : "normal"
275473
+ };
275474
+ }
275475
+ function buildFontString(run2, fontContext) {
275410
275476
  const parts = [];
275411
275477
  if (run2.italic)
275412
275478
  parts.push("italic");
275413
275479
  if (run2.bold)
275414
275480
  parts.push("bold");
275415
275481
  parts.push(`${run2.fontSize}px`);
275416
- const physicalFamily = resolvePhysical(run2.fontFamily);
275482
+ const physicalFamily = fontContext.resolvePhysical(run2.fontFamily, faceOf(run2));
275417
275483
  if (measurementConfig.mode === "deterministic")
275418
275484
  parts.push(measurementConfig.fonts.fallbackStack.length > 0 ? measurementConfig.fonts.fallbackStack.join(", ") : measurementConfig.fonts.deterministicFamily);
275419
275485
  else
@@ -275478,17 +275544,17 @@ function calculateEmptyParagraphMetrics(fontSize, spacing, fontInfo) {
275478
275544
  function lineHeightFontSize(run2) {
275479
275545
  return resolveBaseFontSizeForVerticalText(run2.fontSize, run2);
275480
275546
  }
275481
- function getFontInfoFromRun(run2) {
275547
+ function getFontInfoFromRun(run2, fontContext) {
275482
275548
  return {
275483
- fontFamily: normalizeFontFamily(run2.fontFamily),
275549
+ fontFamily: normalizeFontFamily(fontContext.resolvePhysical(run2.fontFamily, faceOf(run2))),
275484
275550
  fontSize: normalizeFontSize2(lineHeightFontSize(run2)),
275485
275551
  bold: run2.bold,
275486
275552
  italic: run2.italic
275487
275553
  };
275488
275554
  }
275489
- function updateMaxFontInfo(currentMaxSize, currentMaxInfo, newRun) {
275555
+ function updateMaxFontInfo(currentMaxSize, currentMaxInfo, newRun, fontContext) {
275490
275556
  if (lineHeightFontSize(newRun) >= currentMaxSize)
275491
- return getFontInfoFromRun(newRun);
275557
+ return getFontInfoFromRun(newRun, fontContext);
275492
275558
  return currentMaxInfo;
275493
275559
  }
275494
275560
  function isTextRun$22(run2) {
@@ -275506,7 +275572,7 @@ function isLineBreakRun(run2) {
275506
275572
  function isFieldAnnotationRun(run2) {
275507
275573
  return run2.kind === "fieldAnnotation";
275508
275574
  }
275509
- function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator = ".", resolvePhysical = resolvePhysicalFamily) {
275575
+ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator = ".", fontContext) {
275510
275576
  const result = {
275511
275577
  totalWidth: 0,
275512
275578
  runs: [],
@@ -275527,7 +275593,7 @@ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator
275527
275593
  const textRun = run2;
275528
275594
  const text5 = textRun.text || "";
275529
275595
  if (text5.length > 0) {
275530
- const { font } = buildFontString(textRun, resolvePhysical);
275596
+ const { font } = buildFontString(textRun, fontContext);
275531
275597
  const width = measureRunWidth(text5, font, ctx$1, textRun, 0);
275532
275598
  let beforeDecimalWidth;
275533
275599
  if (!foundDecimal) {
@@ -275581,7 +275647,7 @@ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator
275581
275647
  fontSize,
275582
275648
  bold: run2.bold,
275583
275649
  italic: run2.italic
275584
- }, resolvePhysical);
275650
+ }, fontContext);
275585
275651
  const pillWidth = (run2.displayLabel ? measureRunWidth(run2.displayLabel, font, ctx$1, run2, 0) : 0) + FIELD_ANNOTATION_PILL_PADDING;
275586
275652
  result.runs.push({
275587
275653
  runIndex: i4,
@@ -275597,25 +275663,25 @@ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator
275597
275663
  }
275598
275664
  return result;
275599
275665
  }
275600
- async function measureBlock(block, constraints, resolvePhysical = resolvePhysicalFamily) {
275666
+ async function measureBlock(block, constraints, fontContext = DEFAULT_FONT_MEASURE_CONTEXT) {
275601
275667
  const normalized = normalizeConstraints(constraints);
275602
275668
  if (block.kind === "drawing")
275603
275669
  return measureDrawingBlock(block, normalized);
275604
275670
  if (block.kind === "image")
275605
275671
  return measureImageBlock(block, normalized);
275606
275672
  if (block.kind === "list")
275607
- return measureListBlock(block, normalized, resolvePhysical);
275673
+ return measureListBlock(block, normalized, fontContext);
275608
275674
  if (block.kind === "table")
275609
- return measureTableBlock(block, normalized, resolvePhysical);
275675
+ return measureTableBlock(block, normalized, fontContext);
275610
275676
  if (block.kind === "sectionBreak")
275611
275677
  return { kind: "sectionBreak" };
275612
275678
  if (block.kind === "pageBreak")
275613
275679
  return { kind: "pageBreak" };
275614
275680
  if (block.kind === "columnBreak")
275615
275681
  return { kind: "columnBreak" };
275616
- return measureParagraphBlock(block, normalized.maxWidth, resolvePhysical);
275682
+ return measureParagraphBlock(block, normalized.maxWidth, fontContext);
275617
275683
  }
275618
- async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolvePhysicalFamily) {
275684
+ async function measureParagraphBlock(block, maxWidth, fontContext) {
275619
275685
  const ctx$1 = getCanvasContext();
275620
275686
  const wordLayout = block.attrs?.wordLayout;
275621
275687
  const firstTextRunWithSize = block.runs.find((run2) => isTextRun$22(run2) && ("fontSize" in run2) && run2.fontSize != null);
@@ -275628,7 +275694,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
275628
275694
  fontSize: wordLayout.marker.run.fontSize ?? fallbackFontSize,
275629
275695
  bold: wordLayout.marker.run.bold,
275630
275696
  italic: wordLayout.marker.run.italic
275631
- }, resolvePhysical);
275697
+ }, fontContext);
275632
275698
  const markerText = wordLayout.marker.markerText ?? "";
275633
275699
  const glyphWidth = markerText ? measureText(markerText, markerFont, ctx$1) : 0;
275634
275700
  const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : 8;
@@ -275661,7 +275727,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
275661
275727
  fontSize: marker.run?.fontSize ?? fallbackFontSize,
275662
275728
  bold: marker.run?.bold ?? false,
275663
275729
  italic: marker.run?.italic ?? false
275664
- }, resolvePhysical);
275730
+ }, fontContext);
275665
275731
  return measureText(markerText, markerFont, ctx$1);
275666
275732
  }) ?? textStartPx;
275667
275733
  if (typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft)
@@ -275685,14 +275751,14 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
275685
275751
  if (!dropCapDescriptor.run || !dropCapDescriptor.run.text || !dropCapDescriptor.lines)
275686
275752
  console.warn("Invalid drop cap descriptor - missing required fields:", dropCapDescriptor);
275687
275753
  else {
275688
- const dropCapMeasured = measureDropCap(ctx$1, dropCapDescriptor, spacing, resolvePhysical);
275754
+ const dropCapMeasured = measureDropCap(ctx$1, dropCapDescriptor, spacing, fontContext);
275689
275755
  dropCapMeasure = dropCapMeasured;
275690
275756
  dropCapDescriptor.measuredWidth = dropCapMeasured.width;
275691
275757
  dropCapDescriptor.measuredHeight = dropCapMeasured.height;
275692
275758
  }
275693
275759
  const emptyParagraphRun = normalizedRuns.length === 1 && isEmptyTextRun2(normalizedRuns[0]) && !isEmptySdtPlaceholderRun(normalizedRuns[0]) ? normalizedRuns[0] : null;
275694
275760
  if (emptyParagraphRun) {
275695
- const metrics = calculateEmptyParagraphMetrics(emptyParagraphRun.fontSize ?? DEFAULT_PARAGRAPH_FONT_SIZE, spacing, getFontInfoFromRun(emptyParagraphRun));
275761
+ const metrics = calculateEmptyParagraphMetrics(emptyParagraphRun.fontSize ?? DEFAULT_PARAGRAPH_FONT_SIZE, spacing, getFontInfoFromRun(emptyParagraphRun, fontContext));
275696
275762
  const emptyLine = {
275697
275763
  fromRun: 0,
275698
275764
  fromChar: 0,
@@ -275729,7 +275795,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
275729
275795
  ...markerInfo ? { marker: markerInfo } : {}
275730
275796
  };
275731
275797
  }
275732
- const fallbackFontInfo = firstTextRunWithSize ? getFontInfoFromRun(firstTextRunWithSize) : undefined;
275798
+ const fallbackFontInfo = firstTextRunWithSize ? getFontInfoFromRun(firstTextRunWithSize, fontContext) : undefined;
275733
275799
  let currentLine = null;
275734
275800
  const getEffectiveWidth = (baseWidth) => {
275735
275801
  if (dropCapMeasure && lines.length < dropCapMeasure.lines && dropCapMeasure.mode === "drop")
@@ -275910,7 +275976,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
275910
275976
  if (lineToTrim.fromRun === lineToTrim.toRun && sliceText.trim().length === 0)
275911
275977
  return;
275912
275978
  const keptText = sliceText.slice(0, Math.max(0, sliceText.length - trimCount));
275913
- const { font } = buildFontString(lastRun, resolvePhysical);
275979
+ const { font } = buildFontString(lastRun, fontContext);
275914
275980
  const fullWidth = measureRunWidth(sliceText, font, ctx$1, lastRun, sliceStart);
275915
275981
  const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx$1, lastRun, sliceStart) : 0;
275916
275982
  const delta = Math.max(0, fullWidth - keptWidth);
@@ -276057,7 +276123,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276057
276123
  toChar: 1,
276058
276124
  width: 0,
276059
276125
  maxFontSize: lastFontSize,
276060
- maxFontInfo: hasSeenTextRun ? undefined : fallbackFontInfo ?? getFontInfoFromRun(run2),
276126
+ maxFontInfo: hasSeenTextRun ? undefined : fallbackFontInfo ?? getFontInfoFromRun(run2, fontContext),
276061
276127
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
276062
276128
  segments: [],
276063
276129
  spaceCount: 0
@@ -276107,7 +276173,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276107
276173
  if (stop) {
276108
276174
  validateTabStopVal(stop);
276109
276175
  if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
276110
- const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx$1, decimalSeparator, resolvePhysical);
276176
+ const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx$1, decimalSeparator, fontContext);
276111
276177
  if (groupMeasure.totalWidth > 0) {
276112
276178
  const relativeTarget = clampedTarget - effectiveIndent;
276113
276179
  let groupStartX;
@@ -276283,7 +276349,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276283
276349
  if (isFieldAnnotationRun(run2)) {
276284
276350
  const displayText = applyTextTransform(run2.displayLabel || "", run2);
276285
276351
  const annotationFontSize = typeof run2.fontSize === "number" ? run2.fontSize : typeof run2.fontSize === "string" ? parseFloat(run2.fontSize) || DEFAULT_FIELD_ANNOTATION_FONT_SIZE : DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
276286
- const annotationFontFamily = run2.fontFamily || "Arial, sans-serif";
276352
+ const annotationFontFamily = fontContext.resolvePhysical(run2.fontFamily || "Arial, sans-serif", faceOf(run2));
276287
276353
  const fontWeight = run2.bold ? "bold" : "normal";
276288
276354
  ctx$1.font = `${run2.italic ? "italic" : "normal"} ${fontWeight} ${annotationFontSize}px ${annotationFontFamily}`;
276289
276355
  const textWidth = displayText ? ctx$1.measureText(displayText).width : 0;
@@ -276384,7 +276450,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276384
276450
  continue;
276385
276451
  }
276386
276452
  if (isEmptySdtPlaceholderRun(run2)) {
276387
- const placeholderFont = buildFontString(run2, resolvePhysical).font;
276453
+ const placeholderFont = buildFontString(run2, fontContext).font;
276388
276454
  const placeholderText = applyTextTransform(EMPTY_SDT_PLACEHOLDER_TEXT, run2);
276389
276455
  const measuredPlaceholderWidth = getMeasuredTextWidth(placeholderText, placeholderFont, run2.letterSpacing ?? 0, ctx$1);
276390
276456
  const fallbackPlaceholderWidth = placeholderText.length * run2.fontSize * 0.45;
@@ -276397,7 +276463,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276397
276463
  toChar: 0,
276398
276464
  width: placeholderWidth,
276399
276465
  maxFontSize: lineHeightFontSize(run2),
276400
- maxFontInfo: getFontInfoFromRun(run2),
276466
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276401
276467
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
276402
276468
  segments: [{
276403
276469
  runIndex,
@@ -276430,7 +276496,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276430
276496
  toChar: 0,
276431
276497
  width: placeholderWidth,
276432
276498
  maxFontSize: lineHeightFontSize(run2),
276433
- maxFontInfo: getFontInfoFromRun(run2),
276499
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276434
276500
  maxWidth: getEffectiveWidth(bodyContentWidth),
276435
276501
  segments: [{
276436
276502
  runIndex,
@@ -276444,7 +276510,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276444
276510
  currentLine.toRun = runIndex;
276445
276511
  currentLine.toChar = 0;
276446
276512
  currentLine.width = roundValue(currentLine.width + boundarySpacing + placeholderWidth);
276447
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
276513
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
276448
276514
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
276449
276515
  appendSegment(currentLine.segments, runIndex, 0, 0, placeholderWidth);
276450
276516
  }
@@ -276456,7 +276522,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276456
276522
  }
276457
276523
  lastFontSize = run2.fontSize;
276458
276524
  hasSeenTextRun = true;
276459
- const { font } = buildFontString(run2, resolvePhysical);
276525
+ const { font } = buildFontString(run2, fontContext);
276460
276526
  const tabSegments = run2.text.split("\t");
276461
276527
  let charPosInRun = 0;
276462
276528
  for (let segmentIndex = 0;segmentIndex < tabSegments.length; segmentIndex++) {
@@ -276476,7 +276542,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276476
276542
  toChar: spacesEndChar,
276477
276543
  width: spacesWidth,
276478
276544
  maxFontSize: lineHeightFontSize(run2),
276479
- maxFontInfo: getFontInfoFromRun(run2),
276545
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276480
276546
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
276481
276547
  segments: [{
276482
276548
  runIndex,
@@ -276508,7 +276574,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276508
276574
  toChar: spacesEndChar,
276509
276575
  width: spacesWidth,
276510
276576
  maxFontSize: lineHeightFontSize(run2),
276511
- maxFontInfo: getFontInfoFromRun(run2),
276577
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276512
276578
  maxWidth: getEffectiveWidth(bodyContentWidth),
276513
276579
  segments: [{
276514
276580
  runIndex,
@@ -276522,7 +276588,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276522
276588
  currentLine.toRun = runIndex;
276523
276589
  currentLine.toChar = spacesEndChar;
276524
276590
  currentLine.width = roundValue(currentLine.width + boundarySpacing + spacesWidth);
276525
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
276591
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
276526
276592
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
276527
276593
  appendSegment(currentLine.segments, runIndex, spacesStartChar, spacesEndChar, spacesWidth);
276528
276594
  currentLine.spaceCount += spacesLength;
@@ -276575,7 +276641,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276575
276641
  toChar: spaceEndChar,
276576
276642
  width: singleSpaceWidth,
276577
276643
  maxFontSize: lineHeightFontSize(run2),
276578
- maxFontInfo: getFontInfoFromRun(run2),
276644
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276579
276645
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
276580
276646
  segments: [{
276581
276647
  runIndex,
@@ -276609,7 +276675,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276609
276675
  toChar: spaceEndChar,
276610
276676
  width: singleSpaceWidth,
276611
276677
  maxFontSize: lineHeightFontSize(run2),
276612
- maxFontInfo: getFontInfoFromRun(run2),
276678
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276613
276679
  maxWidth: getEffectiveWidth(bodyContentWidth),
276614
276680
  segments: [{
276615
276681
  runIndex,
@@ -276623,7 +276689,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276623
276689
  currentLine.toRun = runIndex;
276624
276690
  currentLine.toChar = spaceEndChar;
276625
276691
  currentLine.width = roundValue(currentLine.width + boundarySpacing$1 + singleSpaceWidth);
276626
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
276692
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
276627
276693
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
276628
276694
  let spaceExplicitX;
276629
276695
  let spacePrecedingTabEndX;
@@ -276679,7 +276745,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276679
276745
  currentLine.toChar = chunkEndChar;
276680
276746
  currentLine.width = roundValue(currentLine.width + chunk.width);
276681
276747
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
276682
- currentLine.maxFontInfo = getFontInfoFromRun(run2);
276748
+ currentLine.maxFontInfo = getFontInfoFromRun(run2, fontContext);
276683
276749
  currentLine.segments.push({
276684
276750
  runIndex,
276685
276751
  fromChar: chunkStartChar,
@@ -276718,7 +276784,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276718
276784
  toChar: chunkEndChar,
276719
276785
  width: chunk.width,
276720
276786
  maxFontSize: lineHeightFontSize(run2),
276721
- maxFontInfo: getFontInfoFromRun(run2),
276787
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276722
276788
  maxWidth: getEffectiveWidth(contentWidth),
276723
276789
  segments: [{
276724
276790
  runIndex,
@@ -276738,7 +276804,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276738
276804
  charPosInRun = wordEndWithSpace;
276739
276805
  } else {
276740
276806
  const chunkLineMaxWidth = getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
276741
- const metrics = calculateTypographyMetrics(run2.fontSize, spacing, getFontInfoFromRun(run2));
276807
+ const metrics = calculateTypographyMetrics(run2.fontSize, spacing, getFontInfoFromRun(run2, fontContext));
276742
276808
  const chunkLine = {
276743
276809
  fromRun: runIndex,
276744
276810
  fromChar: chunkStartChar,
@@ -276770,7 +276836,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276770
276836
  toChar: wordEndNoSpace,
276771
276837
  width: wordOnlyWidth,
276772
276838
  maxFontSize: lineHeightFontSize(run2),
276773
- maxFontInfo: getFontInfoFromRun(run2),
276839
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276774
276840
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
276775
276841
  segments: [{
276776
276842
  runIndex,
@@ -276838,7 +276904,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276838
276904
  toChar: wordEndNoSpace,
276839
276905
  width: wordOnlyWidth,
276840
276906
  maxFontSize: lineHeightFontSize(run2),
276841
- maxFontInfo: getFontInfoFromRun(run2),
276907
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276842
276908
  maxWidth: getEffectiveWidth(bodyContentWidth),
276843
276909
  segments: [{
276844
276910
  runIndex,
@@ -276864,7 +276930,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276864
276930
  if (shouldIncludeDelimiterSpace && currentLine.width + boundarySpacing + wordOnlyWidth + spaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX$1) {
276865
276931
  currentLine.toChar = wordEndNoSpace;
276866
276932
  currentLine.width = roundValue(currentLine.width + boundarySpacing + wordOnlyWidth);
276867
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
276933
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
276868
276934
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
276869
276935
  let explicitXHere;
276870
276936
  if (inActiveTabGroup && activeTabGroup) {
@@ -276900,7 +276966,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276900
276966
  if (compressedWidth != null)
276901
276967
  currentLine.naturalWidth = roundValue(totalWidthWithWord);
276902
276968
  currentLine.width = roundValue(targetWidth);
276903
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
276969
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
276904
276970
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
276905
276971
  appendSegment(currentLine.segments, runIndex, wordStartChar, newToChar, wordCommitWidth, explicitX, wordIndex === 0 ? consumeSegmentPrecedingTabEndX() : undefined);
276906
276972
  if (shouldIncludeDelimiterSpace)
@@ -276930,7 +276996,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276930
276996
  toChar: charPosInRun,
276931
276997
  width: 0,
276932
276998
  maxFontSize: lineHeightFontSize(run2),
276933
- maxFontInfo: getFontInfoFromRun(run2),
276999
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
276934
277000
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
276935
277001
  segments: [],
276936
277002
  spaceCount: 0
@@ -276946,7 +277012,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
276946
277012
  currentLine.width = roundValue(currentLine.width + tabAdvance);
276947
277013
  if (stop?.source === "explicit")
276948
277014
  currentLine.hasExplicitTabStops = true;
276949
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
277015
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
276950
277016
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
276951
277017
  currentLine.toRun = runIndex;
276952
277018
  currentLine.toChar = charPosInRun;
@@ -277010,9 +277076,9 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
277010
277076
  ...dropCapMeasure ? { dropCap: dropCapMeasure } : {}
277011
277077
  };
277012
277078
  }
277013
- async function measureTableBlock(block, constraints, resolvePhysical = resolvePhysicalFamily) {
277079
+ async function measureTableBlock(block, constraints, fontContext) {
277014
277080
  const workingInput = buildAutoFitWorkingGridInput(block, { maxWidth: typeof constraints === "number" ? constraints : constraints.maxWidth });
277015
- const columnWidths = await resolveRuntimeTableColumnWidths(block, workingInput);
277081
+ const columnWidths = await resolveRuntimeTableColumnWidths(block, workingInput, fontContext);
277016
277082
  const gridColumnCount = columnWidths.length;
277017
277083
  const calculateCellWidth = (startCol, colspan) => {
277018
277084
  let width = 0;
@@ -277063,7 +277129,7 @@ async function measureTableBlock(block, constraints, resolvePhysical = resolvePh
277063
277129
  const measure = await measureBlock(block$1, {
277064
277130
  maxWidth: contentWidth$1,
277065
277131
  maxHeight: Infinity
277066
- }, resolvePhysical);
277132
+ }, fontContext);
277067
277133
  blockMeasures.push(measure);
277068
277134
  const blockHeight = "totalHeight" in measure ? measure.totalHeight : ("height" in measure) ? measure.height : 0;
277069
277135
  if ((block$1.kind === "image" || block$1.kind === "drawing") && block$1.anchor?.isAnchored === true && (block$1.wrap?.type ?? "Inline") !== "Inline")
@@ -277151,14 +277217,15 @@ async function measureTableBlock(block, constraints, resolvePhysical = resolvePh
277151
277217
  tableBorderWidths: borderWidthH > 0 || borderWidthV > 0 ? tableBorderWidths : undefined
277152
277218
  };
277153
277219
  }
277154
- async function resolveRuntimeTableColumnWidths(block, workingInput) {
277220
+ async function resolveRuntimeTableColumnWidths(block, workingInput, fontContext) {
277155
277221
  const fixedLayout = computeFixedTableColumnWidths(workingInput);
277156
277222
  if (workingInput.layoutMode === "fixed")
277157
277223
  return fixedLayout.columnWidths;
277158
- const { contentMetrics, cellMetricKeys } = await buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout);
277224
+ const { contentMetrics, cellMetricKeys } = await buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout, fontContext);
277159
277225
  const cacheKey = buildAutoFitTableResultCacheKey(block, {
277160
277226
  maxWidth: workingInput.maxTableWidth,
277161
277227
  cellMetricKeys,
277228
+ fontSignature: fontContext.fontSignature,
277162
277229
  workingInput,
277163
277230
  fixedLayout
277164
277231
  });
@@ -277176,8 +277243,9 @@ async function resolveRuntimeTableColumnWidths(block, workingInput) {
277176
277243
  });
277177
277244
  return result.columnWidths;
277178
277245
  }
277179
- async function buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout) {
277180
- const contentMetrics = await measureTableAutoFitContentMetrics(block, workingInput, fixedLayout, measureBlock);
277246
+ async function buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout, fontContext) {
277247
+ const measureBlockWithFontContext = (childBlock, childConstraints) => measureBlock(childBlock, childConstraints, fontContext);
277248
+ const contentMetrics = await measureTableAutoFitContentMetrics(block, workingInput, fixedLayout, measureBlockWithFontContext, fontContext);
277181
277249
  return {
277182
277250
  contentMetrics,
277183
277251
  cellMetricKeys: contentMetrics.cellMetricKeys
@@ -277291,7 +277359,7 @@ function normalizeConstraints(constraints) {
277291
277359
  return { maxWidth: constraints };
277292
277360
  return constraints;
277293
277361
  }
277294
- async function measureListBlock(block, constraints, resolvePhysical = resolvePhysicalFamily) {
277362
+ async function measureListBlock(block, constraints, fontContext) {
277295
277363
  const ctx$1 = getCanvasContext();
277296
277364
  const items = [];
277297
277365
  let totalHeight = 0;
@@ -277310,12 +277378,12 @@ async function measureListBlock(block, constraints, resolvePhysical = resolvePhy
277310
277378
  bold: marker.run.bold,
277311
277379
  italic: marker.run.italic,
277312
277380
  letterSpacing: marker.run.letterSpacing
277313
- }, resolvePhysical);
277381
+ }, fontContext);
277314
277382
  markerTextWidth = marker.markerText ? measureText(marker.markerText, markerFont, ctx$1) : 0;
277315
277383
  markerWidth = 0;
277316
277384
  indentLeft = wordLayout.indentLeftPx ?? 0;
277317
277385
  } else {
277318
- const { font: markerFont } = buildFontString(getPrimaryRun(item.paragraph), resolvePhysical);
277386
+ const { font: markerFont } = buildFontString(getPrimaryRun(item.paragraph), fontContext);
277319
277387
  const markerText = item.marker.text ?? "";
277320
277388
  markerTextWidth = markerText ? measureText(markerText, markerFont, ctx$1) : 0;
277321
277389
  indentLeft = resolveIndentLeft(item);
@@ -277323,7 +277391,7 @@ async function measureListBlock(block, constraints, resolvePhysical = resolvePhy
277323
277391
  markerWidth = Math.max(24, markerTextWidth + 8, indentHanging);
277324
277392
  }
277325
277393
  const paragraphWidth = Math.max(1, constraints.maxWidth - indentLeft - markerWidth);
277326
- const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth, resolvePhysical);
277394
+ const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth, fontContext);
277327
277395
  totalHeight += paragraphMeasure.totalHeight;
277328
277396
  items.push({
277329
277397
  itemId: item.id,
@@ -277339,7 +277407,7 @@ async function measureListBlock(block, constraints, resolvePhysical = resolvePhy
277339
277407
  totalHeight
277340
277408
  };
277341
277409
  }
277342
- async function layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, deps, fontResolver) {
277410
+ async function layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, deps, fontResolver, hasFace, effectiveSignature) {
277343
277411
  deps.headerLayoutsByRId.clear();
277344
277412
  deps.footerLayoutsByRId.clear();
277345
277413
  if (!headerFooterInput)
@@ -277362,27 +277430,30 @@ async function layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetad
277362
277430
  };
277363
277431
  };
277364
277432
  if (sectionMetadata.length > 1 && sectionMetadata.some((s2) => s2.margins || s2.pageSize)) {
277365
- await layoutWithPerSectionConstraints("header", headerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.headerLayoutsByRId, fontResolver);
277366
- await layoutWithPerSectionConstraints("footer", footerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.footerLayoutsByRId, fontResolver);
277433
+ await layoutWithPerSectionConstraints("header", headerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.headerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
277434
+ await layoutWithPerSectionConstraints("footer", footerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.footerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
277367
277435
  } else {
277368
277436
  const effectiveHeaderRefsBySection = buildEffectiveHeaderFooterRefsBySection(sectionMetadata, "header");
277369
277437
  const effectiveFooterRefsBySection = buildEffectiveHeaderFooterRefsBySection(sectionMetadata, "footer");
277370
- await layoutBlocksByRId("header", headerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveHeaderRefsBySection), constraints, pageResolver, deps.headerLayoutsByRId, fontResolver);
277371
- await layoutBlocksByRId("footer", footerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveFooterRefsBySection), constraints, pageResolver, deps.footerLayoutsByRId, fontResolver);
277438
+ await layoutBlocksByRId("header", headerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveHeaderRefsBySection), constraints, pageResolver, deps.headerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
277439
+ await layoutBlocksByRId("footer", footerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveFooterRefsBySection), constraints, pageResolver, deps.footerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
277372
277440
  }
277373
277441
  }
277374
- async function layoutBlocksByRId(kind, blocksByRId, referencedRIds, constraints, pageResolver, layoutsByRId, fontResolver) {
277442
+ async function layoutBlocksByRId(kind, blocksByRId, referencedRIds, constraints, pageResolver, layoutsByRId, fontResolver, hasFace, effectiveSignature) {
277375
277443
  if (!blocksByRId || referencedRIds.size === 0)
277376
277444
  return;
277377
- const resolvePhysical = fontResolver ? (css) => fontResolver.resolvePhysicalFamily(css) : undefined;
277378
- const fontSignature = fontResolver?.signature ?? "";
277445
+ const fontSignature = effectiveSignature ?? "";
277446
+ const fontMeasureContext = fontResolver ? {
277447
+ resolvePhysical: (css, face) => hasFace ? fontResolver.resolvePhysicalFamilyForFace(css, face, hasFace) : fontResolver.resolvePhysicalFamily(css),
277448
+ fontSignature
277449
+ } : undefined;
277379
277450
  for (const [rId, blocks2] of blocksByRId) {
277380
277451
  if (!referencedRIds.has(rId))
277381
277452
  continue;
277382
277453
  if (!blocks2 || blocks2.length === 0)
277383
277454
  continue;
277384
277455
  try {
277385
- const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, (block, c) => measureBlock(block, c, resolvePhysical), undefined, undefined, pageResolver, kind, fontSignature);
277456
+ const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature);
277386
277457
  if (batchResult.default)
277387
277458
  layoutsByRId.set(rId, {
277388
277459
  kind,
@@ -277428,18 +277499,21 @@ function adjustFramePositionsForContentWidth(layout, blocks2, effectiveWidth, co
277428
277499
  fragment.x -= widthDiff / 2;
277429
277500
  }
277430
277501
  }
277431
- async function layoutWithPerSectionConstraints(kind, blocksByRId, sectionMetadata, fallbackConstraints, pageResolver, layoutsByRId, fontResolver) {
277502
+ async function layoutWithPerSectionConstraints(kind, blocksByRId, sectionMetadata, fallbackConstraints, pageResolver, layoutsByRId, fontResolver, hasFace, effectiveSignature) {
277432
277503
  if (!blocksByRId)
277433
277504
  return;
277434
- const resolvePhysical = fontResolver ? (css) => fontResolver.resolvePhysicalFamily(css) : undefined;
277435
- const fontSignature = fontResolver?.signature ?? "";
277505
+ const fontSignature = effectiveSignature ?? "";
277506
+ const fontMeasureContext = fontResolver ? {
277507
+ resolvePhysical: (css, face) => hasFace ? fontResolver.resolvePhysicalFamilyForFace(css, face, hasFace) : fontResolver.resolvePhysicalFamily(css),
277508
+ fontSignature
277509
+ } : undefined;
277436
277510
  const groups = buildSectionAwareHeaderFooterMeasurementGroups(kind, blocksByRId, sectionMetadata, fallbackConstraints);
277437
277511
  for (const group of groups) {
277438
277512
  const blocks2 = blocksByRId.get(group.rId);
277439
277513
  if (!blocks2 || blocks2.length === 0)
277440
277514
  continue;
277441
277515
  try {
277442
- const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, (block, c) => measureBlock(block, c, resolvePhysical), undefined, undefined, pageResolver, kind, fontSignature);
277516
+ const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature);
277443
277517
  if (batchResult.default)
277444
277518
  for (const sectionIndex of group.sectionIndices) {
277445
277519
  const contentWidth = buildSectionContentWidth(sectionMetadata.find((s2) => s2.sectionIndex === sectionIndex), fallbackConstraints);
@@ -278089,80 +278163,146 @@ function defaultInvalidate() {
278089
278163
  clearTextMeasurementCaches();
278090
278164
  measureCache.clear();
278091
278165
  }
278092
- function faceKey(req) {
278093
- return `${req.family.toLowerCase()}|${req.weight}|${req.style}`;
278166
+ function toCssFontSource(url2) {
278167
+ return /^\s*url\(/i.test(url2) ? url2 : `url(${JSON.stringify(url2)})`;
278168
+ }
278169
+ function defaultScheduleMicrotask(callback) {
278170
+ if (typeof queueMicrotask === "function") {
278171
+ queueMicrotask(callback);
278172
+ return;
278173
+ }
278174
+ Promise.resolve().then(callback);
278175
+ }
278176
+ function primaryFamily(css) {
278177
+ const comma = css.indexOf(",");
278178
+ return (comma === -1 ? css : css.slice(0, comma)).trim().replace(/^["']|["']$/g, "");
278094
278179
  }
278095
- function collect(out, node2, resolve2) {
278180
+ function makeResolveFace(resolver2, hasFace) {
278181
+ if (resolver2 && hasFace)
278182
+ return (logical, face) => {
278183
+ const r$1 = resolver2.resolveFace(logical, face, hasFace);
278184
+ return {
278185
+ physicalFamily: r$1.physicalFamily,
278186
+ reason: r$1.reason
278187
+ };
278188
+ };
278189
+ if (resolver2)
278190
+ return (logical) => {
278191
+ const r$1 = resolver2.resolveFontFamily(logical);
278192
+ return {
278193
+ physicalFamily: r$1.physicalFamily,
278194
+ reason: r$1.reason
278195
+ };
278196
+ };
278197
+ return (logical) => {
278198
+ const r$1 = resolveFontFamily2(logical);
278199
+ return {
278200
+ physicalFamily: r$1.physicalFamily,
278201
+ reason: r$1.reason
278202
+ };
278203
+ };
278204
+ }
278205
+ function collect(acc, node2, resolveFace$1) {
278096
278206
  if (!node2 || typeof node2.fontFamily !== "string" || !node2.fontFamily)
278097
278207
  return;
278098
- const family$1 = resolve2(node2.fontFamily);
278099
- if (!family$1)
278208
+ const weight = node2.bold === true ? "700" : "400";
278209
+ const style2 = node2.italic === true ? "italic" : "normal";
278210
+ const logicalPrimary = primaryFamily(node2.fontFamily);
278211
+ if (!logicalPrimary)
278100
278212
  return;
278101
- const req = {
278102
- family: family$1,
278103
- weight: node2.bold === true ? "700" : "400",
278104
- style: node2.italic === true ? "italic" : "normal"
278105
- };
278106
- const key2 = faceKey(req);
278107
- if (!out.has(key2))
278108
- out.set(key2, req);
278213
+ const usedKey = `${logicalPrimary.toLowerCase()}|${weight}|${style2}`;
278214
+ if (acc.usedFaces.has(usedKey))
278215
+ return;
278216
+ const { physicalFamily, reason } = resolveFace$1(node2.fontFamily, {
278217
+ weight,
278218
+ style: style2
278219
+ });
278220
+ acc.usedFaces.set(usedKey, {
278221
+ logicalFamily: logicalPrimary,
278222
+ weight,
278223
+ style: style2
278224
+ });
278225
+ acc.sigEntries.set(usedKey, [
278226
+ logicalPrimary.toLowerCase(),
278227
+ weight,
278228
+ style2,
278229
+ (physicalFamily || "").toLowerCase(),
278230
+ reason
278231
+ ]);
278232
+ if (physicalFamily) {
278233
+ const reqKey = `${physicalFamily.toLowerCase()}|${weight}|${style2}`;
278234
+ if (!acc.requiredFaces.has(reqKey))
278235
+ acc.requiredFaces.set(reqKey, {
278236
+ family: physicalFamily,
278237
+ weight,
278238
+ style: style2
278239
+ });
278240
+ }
278109
278241
  }
278110
- function collectRuns(out, runs2, resolve2) {
278242
+ function collectRuns(acc, runs2, resolveFace$1) {
278111
278243
  if (!runs2)
278112
278244
  return;
278113
278245
  for (const run2 of runs2) {
278114
278246
  const bearing = run2;
278115
278247
  if (run2.kind === "fieldAnnotation" && (typeof bearing.fontFamily !== "string" || !bearing.fontFamily))
278116
- collect(out, {
278248
+ collect(acc, {
278117
278249
  ...bearing,
278118
278250
  fontFamily: "Arial"
278119
- }, resolve2);
278251
+ }, resolveFace$1);
278120
278252
  else
278121
- collect(out, bearing, resolve2);
278253
+ collect(acc, bearing, resolveFace$1);
278122
278254
  }
278123
278255
  }
278124
- function collectParagraph(out, paragraph2, resolve2) {
278256
+ function collectParagraph(acc, paragraph2, resolveFace$1) {
278125
278257
  if (!paragraph2)
278126
278258
  return;
278127
- collectRuns(out, paragraph2.runs, resolve2);
278128
- collect(out, paragraph2.attrs?.wordLayout?.marker?.run, resolve2);
278129
- collect(out, paragraph2.attrs?.dropCapDescriptor?.run, resolve2);
278259
+ collectRuns(acc, paragraph2.runs, resolveFace$1);
278260
+ collect(acc, paragraph2.attrs?.wordLayout?.marker?.run, resolveFace$1);
278261
+ collect(acc, paragraph2.attrs?.dropCapDescriptor?.run, resolveFace$1);
278130
278262
  }
278131
- function collectTable(out, table2, resolve2) {
278263
+ function collectTable(acc, table2, resolveFace$1) {
278132
278264
  for (const row2 of table2.rows)
278133
278265
  for (const cell2 of row2.cells) {
278134
- collectParagraph(out, cell2.paragraph, resolve2);
278266
+ collectParagraph(acc, cell2.paragraph, resolveFace$1);
278135
278267
  if (cell2.blocks)
278136
278268
  for (const b$1 of cell2.blocks)
278137
- collectBlock(out, b$1, resolve2);
278269
+ collectBlock(acc, b$1, resolveFace$1);
278138
278270
  }
278139
278271
  }
278140
- function collectList(out, list5, resolve2) {
278272
+ function collectList(acc, list5, resolveFace$1) {
278141
278273
  for (const item of list5.items)
278142
- collectParagraph(out, item.paragraph, resolve2);
278274
+ collectParagraph(acc, item.paragraph, resolveFace$1);
278143
278275
  }
278144
- function collectBlock(out, block, resolve2) {
278276
+ function collectBlock(acc, block, resolveFace$1) {
278145
278277
  switch (block.kind) {
278146
278278
  case "paragraph":
278147
- collectParagraph(out, block, resolve2);
278279
+ collectParagraph(acc, block, resolveFace$1);
278148
278280
  break;
278149
278281
  case "table":
278150
- collectTable(out, block, resolve2);
278282
+ collectTable(acc, block, resolveFace$1);
278151
278283
  break;
278152
278284
  case "list":
278153
- collectList(out, block, resolve2);
278285
+ collectList(acc, block, resolveFace$1);
278154
278286
  break;
278155
278287
  default:
278156
278288
  break;
278157
278289
  }
278158
278290
  }
278159
- function planRequiredFontFaces(blocks2, resolver2) {
278160
- const resolve2 = resolver2 ? (family$1) => resolver2.resolvePrimaryPhysicalFamily(family$1) : resolvePrimaryPhysicalFamily;
278161
- const out = /* @__PURE__ */ new Map;
278291
+ function planFontFaces(blocks2, resolver2, hasFace) {
278292
+ const resolveFace$1 = makeResolveFace(resolver2, hasFace);
278293
+ const acc = {
278294
+ requiredFaces: /* @__PURE__ */ new Map,
278295
+ usedFaces: /* @__PURE__ */ new Map,
278296
+ sigEntries: /* @__PURE__ */ new Map
278297
+ };
278162
278298
  if (blocks2)
278163
278299
  for (const block of blocks2)
278164
- collectBlock(out, block, resolve2);
278165
- return [...out.values()];
278300
+ collectBlock(acc, block, resolveFace$1);
278301
+ return {
278302
+ requiredFaces: [...acc.requiredFaces.values()],
278303
+ usedFaces: [...acc.usedFaces.values()],
278304
+ effectiveSignature: acc.sigEntries.size === 0 ? "" : JSON.stringify([...acc.sigEntries.entries()].sort(([a2], [b$1]) => a2 < b$1 ? -1 : a2 > b$1 ? 1 : 0).map(([, tuple3]) => tuple3))
278305
+ };
278166
278306
  }
278167
278307
  function buildSemanticFootnoteBlocks(input2, footnotesMode) {
278168
278308
  if (!input2 || input2.refs.length === 0 || input2.blocksById.size === 0)
@@ -299242,7 +299382,407 @@ menclose::after {
299242
299382
  const minReadablePx = getMinimumReadableTextStartPx(markerContentEndPx, gutterWidthPx);
299243
299383
  return Math.max(nextTabStopPx, minReadablePx);
299244
299384
  }
299245
- }, hashParagraphBorder$2 = (border) => {
299385
+ }, SETTLED_STATUSES, BUNDLED_SUBSTITUTES, FontResolver = class {
299386
+ #overrides = /* @__PURE__ */ new Map;
299387
+ #version = 0;
299388
+ #cachedSignature = null;
299389
+ map(logicalFamily, physicalFamily) {
299390
+ const key2 = normalizeFamilyKey$2(logicalFamily);
299391
+ const physical = physicalFamily?.trim();
299392
+ if (!key2 || !physical)
299393
+ return;
299394
+ if (this.#overrides.get(key2) === physical)
299395
+ return;
299396
+ if ((BUNDLED_SUBSTITUTES[key2] ?? logicalFamily.trim()) === physical) {
299397
+ if (this.#overrides.delete(key2)) {
299398
+ this.#version += 1;
299399
+ this.#cachedSignature = null;
299400
+ }
299401
+ return;
299402
+ }
299403
+ this.#overrides.set(key2, physical);
299404
+ this.#version += 1;
299405
+ this.#cachedSignature = null;
299406
+ }
299407
+ unmap(logicalFamily) {
299408
+ if (this.#overrides.delete(normalizeFamilyKey$2(logicalFamily))) {
299409
+ this.#version += 1;
299410
+ this.#cachedSignature = null;
299411
+ }
299412
+ }
299413
+ reset() {
299414
+ if (this.#overrides.size === 0)
299415
+ return;
299416
+ this.#overrides.clear();
299417
+ this.#version += 1;
299418
+ this.#cachedSignature = null;
299419
+ }
299420
+ get version() {
299421
+ return this.#version;
299422
+ }
299423
+ get signature() {
299424
+ if (this.#cachedSignature !== null)
299425
+ return this.#cachedSignature;
299426
+ this.#cachedSignature = this.#overrides.size === 0 ? "" : JSON.stringify([...this.#overrides.entries()].sort(([a2], [b$1]) => a2 < b$1 ? -1 : a2 > b$1 ? 1 : 0));
299427
+ return this.#cachedSignature;
299428
+ }
299429
+ #physicalFor(bareFamily) {
299430
+ const key2 = normalizeFamilyKey$2(bareFamily);
299431
+ const override = this.#overrides.get(key2);
299432
+ if (override)
299433
+ return {
299434
+ physical: override,
299435
+ reason: "custom_mapping"
299436
+ };
299437
+ const bundled = BUNDLED_SUBSTITUTES[key2];
299438
+ if (bundled)
299439
+ return {
299440
+ physical: bundled,
299441
+ reason: "bundled_substitute"
299442
+ };
299443
+ return {
299444
+ physical: bareFamily,
299445
+ reason: "as_requested"
299446
+ };
299447
+ }
299448
+ resolveFontFamily(logicalFamily) {
299449
+ const primary = splitStack(logicalFamily)[0] ?? logicalFamily;
299450
+ const { physical, reason } = this.#physicalFor(primary);
299451
+ return {
299452
+ logicalFamily,
299453
+ physicalFamily: physical,
299454
+ reason
299455
+ };
299456
+ }
299457
+ resolvePhysicalFamily(cssFontFamily) {
299458
+ if (!cssFontFamily)
299459
+ return cssFontFamily;
299460
+ const parts = splitStack(cssFontFamily);
299461
+ if (parts.length === 0)
299462
+ return cssFontFamily;
299463
+ const { physical, reason } = this.#physicalFor(parts[0]);
299464
+ if (reason === "as_requested")
299465
+ return cssFontFamily;
299466
+ return [physical, ...parts.slice(1)].join(", ");
299467
+ }
299468
+ resolveFace(logicalFamily, face, hasFace) {
299469
+ const primary = splitStack(logicalFamily)[0] ?? logicalFamily;
299470
+ const { physical, reason } = this.#physicalFor(primary);
299471
+ if (reason === "as_requested")
299472
+ return {
299473
+ logicalFamily,
299474
+ physicalFamily: physical,
299475
+ reason
299476
+ };
299477
+ if (hasFace(physical, face.weight, face.style))
299478
+ return {
299479
+ logicalFamily,
299480
+ physicalFamily: physical,
299481
+ reason
299482
+ };
299483
+ return {
299484
+ logicalFamily,
299485
+ physicalFamily: primary,
299486
+ reason: "fallback_face_absent"
299487
+ };
299488
+ }
299489
+ resolvePhysicalFamilyForFace(cssFontFamily, face, hasFace) {
299490
+ if (!cssFontFamily)
299491
+ return cssFontFamily;
299492
+ const parts = splitStack(cssFontFamily);
299493
+ if (parts.length === 0)
299494
+ return cssFontFamily;
299495
+ const { physical, reason } = this.#physicalFor(parts[0]);
299496
+ if (reason === "as_requested")
299497
+ return cssFontFamily;
299498
+ if (!hasFace(physical, face.weight, face.style))
299499
+ return cssFontFamily;
299500
+ return [physical, ...parts.slice(1)].join(", ");
299501
+ }
299502
+ resolvePrimaryPhysicalFamily(family$1) {
299503
+ const primary = splitStack(family$1)[0] ?? family$1;
299504
+ return this.#physicalFor(primary).physical;
299505
+ }
299506
+ resolvePhysicalFamilies(families) {
299507
+ const out = /* @__PURE__ */ new Set;
299508
+ for (const family$1 of families)
299509
+ if (family$1)
299510
+ out.add(this.resolvePrimaryPhysicalFamily(family$1));
299511
+ return [...out];
299512
+ }
299513
+ }, defaultResolver, DEFAULT_FONT_MEASURE_CONTEXT, fontConfigVersion = 0, BUNDLED_MANIFEST, defaultAssetBase = "/fonts/", installedRegistries, DEFAULT_FONT_LOAD_TIMEOUT_MS = 3000, DEFAULT_PROBE_SIZE = "16px", FontRegistry = class {
299514
+ #fontSet;
299515
+ #FontFaceCtor;
299516
+ #probeSize;
299517
+ #scheduleTimeout;
299518
+ #cancelTimeout;
299519
+ #managed = /* @__PURE__ */ new Map;
299520
+ #status = /* @__PURE__ */ new Map;
299521
+ #sources = /* @__PURE__ */ new Map;
299522
+ #warnedFailures = /* @__PURE__ */ new Set;
299523
+ #inflight = /* @__PURE__ */ new Map;
299524
+ #faceStatus = /* @__PURE__ */ new Map;
299525
+ #faceInflight = /* @__PURE__ */ new Map;
299526
+ #faceSources = /* @__PURE__ */ new Map;
299527
+ #facesByFamily = /* @__PURE__ */ new Map;
299528
+ #warnedFaceFailures = /* @__PURE__ */ new Set;
299529
+ constructor(options = {}) {
299530
+ this.#fontSet = options.fontSet ?? null;
299531
+ this.#FontFaceCtor = options.FontFaceCtor ?? null;
299532
+ this.#probeSize = options.probeSize ?? DEFAULT_PROBE_SIZE;
299533
+ this.#scheduleTimeout = options.scheduleTimeout ?? ((cb, ms) => globalThis.setTimeout(cb, ms));
299534
+ this.#cancelTimeout = options.cancelTimeout ?? ((handle3) => globalThis.clearTimeout(handle3));
299535
+ }
299536
+ register(descriptor) {
299537
+ const { family: family$1, source, descriptors: descriptors2 } = descriptor;
299538
+ const identitySource = typeof source === "string" ? canonicalizeFontSource(source) : source;
299539
+ const key2 = faceKeyOf$1(family$1, normalizeWeight(descriptors2?.weight), normalizeStyle$1(descriptors2?.style));
299540
+ if (typeof identitySource === "string") {
299541
+ const existingSource = this.#faceSources.get(key2);
299542
+ if (existingSource === identitySource)
299543
+ return {
299544
+ family: family$1,
299545
+ status: this.getStatus(family$1),
299546
+ changed: false
299547
+ };
299548
+ if (existingSource !== undefined)
299549
+ throw new Error(`[superdoc] font face "${key2}" is already registered from a different source ("${existingSource}"); a registered face's source cannot be replaced`);
299550
+ }
299551
+ if (this.#FontFaceCtor && this.#fontSet) {
299552
+ const face = new this.#FontFaceCtor(family$1, source, descriptors2);
299553
+ this.#fontSet.add(face);
299554
+ this.#managed.set(family$1, face);
299555
+ }
299556
+ if (typeof source === "string") {
299557
+ const list5 = this.#sources.get(family$1) ?? [];
299558
+ if (!list5.includes(source))
299559
+ list5.push(source);
299560
+ this.#sources.set(family$1, list5);
299561
+ }
299562
+ if (!this.#status.has(family$1))
299563
+ this.#status.set(family$1, "unloaded");
299564
+ this.#trackFace(family$1, key2);
299565
+ if (!this.#faceStatus.has(key2))
299566
+ this.#faceStatus.set(key2, "unloaded");
299567
+ if (typeof identitySource === "string" && !this.#faceSources.has(key2))
299568
+ this.#faceSources.set(key2, identitySource);
299569
+ return {
299570
+ family: family$1,
299571
+ status: this.getStatus(family$1),
299572
+ changed: true
299573
+ };
299574
+ }
299575
+ #trackFace(family$1, key2) {
299576
+ const fam = normalizeFamilyKey$1(family$1);
299577
+ const set3 = this.#facesByFamily.get(fam) ?? /* @__PURE__ */ new Set;
299578
+ set3.add(key2);
299579
+ this.#facesByFamily.set(fam, set3);
299580
+ }
299581
+ isManaged(family$1) {
299582
+ return this.#managed.has(family$1);
299583
+ }
299584
+ getStatus(family$1) {
299585
+ const statuses = [];
299586
+ const faceKeys = this.#facesByFamily.get(normalizeFamilyKey$1(family$1));
299587
+ if (faceKeys)
299588
+ for (const k$1 of faceKeys)
299589
+ statuses.push(this.#faceStatus.get(k$1) ?? "unloaded");
299590
+ const legacy = this.#status.get(family$1);
299591
+ if (legacy)
299592
+ statuses.push(legacy);
299593
+ if (statuses.length === 0)
299594
+ return "unloaded";
299595
+ for (const s2 of [
299596
+ "failed",
299597
+ "timed_out",
299598
+ "fallback_used",
299599
+ "loaded",
299600
+ "loading",
299601
+ "unloaded"
299602
+ ])
299603
+ if (statuses.includes(s2))
299604
+ return s2;
299605
+ return "unloaded";
299606
+ }
299607
+ hasFace(family$1, weight, style2) {
299608
+ return this.#facesByFamily.get(normalizeFamilyKey$1(family$1))?.has(faceKeyOf$1(family$1, weight, style2)) ?? false;
299609
+ }
299610
+ isAvailable(family$1) {
299611
+ if (!this.#fontSet)
299612
+ return false;
299613
+ try {
299614
+ return this.#fontSet.check(`${this.#probeSize} ${quoteFamily(family$1)}`);
299615
+ } catch {
299616
+ return false;
299617
+ }
299618
+ }
299619
+ awaitFace(family$1, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
299620
+ if (this.#status.get(family$1) === "loaded")
299621
+ return Promise.resolve({
299622
+ family: family$1,
299623
+ status: "loaded"
299624
+ });
299625
+ const existing = this.#inflight.get(family$1);
299626
+ if (existing)
299627
+ return existing;
299628
+ const probe = this.#loadOne(family$1, timeoutMs).finally(() => {
299629
+ this.#inflight.delete(family$1);
299630
+ });
299631
+ this.#inflight.set(family$1, probe);
299632
+ return probe;
299633
+ }
299634
+ async awaitFaces(families, options = {}) {
299635
+ const unique$2 = [...new Set(families)];
299636
+ const timeoutMs = options.timeoutMs ?? 3000;
299637
+ return Promise.all(unique$2.map((family$1) => this.awaitFace(family$1, timeoutMs)));
299638
+ }
299639
+ getRequiredFaces(families, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
299640
+ return [...new Set(families)].map((family$1) => ({
299641
+ family: family$1,
299642
+ status: this.getStatus(family$1),
299643
+ ready: this.awaitFace(family$1, timeoutMs)
299644
+ }));
299645
+ }
299646
+ getStates() {
299647
+ return [...this.#status.entries()].map(([family$1, status]) => ({
299648
+ family: family$1,
299649
+ status
299650
+ }));
299651
+ }
299652
+ getFaceStatus(request) {
299653
+ return this.#faceStatus.get(faceKeyOf$1(request.family, request.weight, request.style)) ?? "unloaded";
299654
+ }
299655
+ awaitFaceRequest(request, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
299656
+ const key2 = faceKeyOf$1(request.family, request.weight, request.style);
299657
+ if (this.#faceStatus.get(key2) === "loaded")
299658
+ return Promise.resolve({
299659
+ request,
299660
+ status: "loaded"
299661
+ });
299662
+ const existing = this.#faceInflight.get(key2);
299663
+ if (existing)
299664
+ return existing;
299665
+ const probe = this.#loadOneFace(request, key2, timeoutMs).finally(() => {
299666
+ this.#faceInflight.delete(key2);
299667
+ });
299668
+ this.#faceInflight.set(key2, probe);
299669
+ return probe;
299670
+ }
299671
+ async awaitFaceRequests(requests, options = {}) {
299672
+ const timeoutMs = options.timeoutMs ?? 3000;
299673
+ const seen = /* @__PURE__ */ new Set;
299674
+ const unique$2 = [];
299675
+ for (const r$1 of requests) {
299676
+ const key2 = faceKeyOf$1(r$1.family, r$1.weight, r$1.style);
299677
+ if (seen.has(key2))
299678
+ continue;
299679
+ seen.add(key2);
299680
+ unique$2.push(r$1);
299681
+ }
299682
+ return Promise.all(unique$2.map((r$1) => this.awaitFaceRequest(r$1, timeoutMs)));
299683
+ }
299684
+ async#loadOneFace(request, key2, timeoutMs) {
299685
+ this.#trackFace(request.family, key2);
299686
+ const fontSet = this.#fontSet;
299687
+ if (!fontSet) {
299688
+ this.#faceStatus.set(key2, "fallback_used");
299689
+ return {
299690
+ request,
299691
+ status: "fallback_used"
299692
+ };
299693
+ }
299694
+ this.#faceStatus.set(key2, "loading");
299695
+ const probe = faceProbe(request.family, request.weight, request.style, this.#probeSize);
299696
+ const TIMEOUT = Symbol("timeout");
299697
+ let handle3;
299698
+ const timeout$1 = new Promise((resolve2) => {
299699
+ handle3 = this.#scheduleTimeout(() => resolve2(TIMEOUT), timeoutMs);
299700
+ });
299701
+ try {
299702
+ const settled = await Promise.race([fontSet.load(probe), timeout$1]);
299703
+ if (settled === TIMEOUT) {
299704
+ this.#faceStatus.set(key2, "timed_out");
299705
+ return {
299706
+ request,
299707
+ status: "timed_out"
299708
+ };
299709
+ }
299710
+ const status = settled.length > 0 ? "loaded" : "fallback_used";
299711
+ this.#faceStatus.set(key2, status);
299712
+ return {
299713
+ request,
299714
+ status
299715
+ };
299716
+ } catch {
299717
+ this.#faceStatus.set(key2, "failed");
299718
+ this.#warnFaceFailureOnce(request, key2);
299719
+ return {
299720
+ request,
299721
+ status: "failed"
299722
+ };
299723
+ } finally {
299724
+ this.#cancelTimeout(handle3);
299725
+ }
299726
+ }
299727
+ #warnFaceFailureOnce(request, key2) {
299728
+ if (this.#warnedFaceFailures.has(key2))
299729
+ return;
299730
+ this.#warnedFaceFailures.add(key2);
299731
+ const src = this.#faceSources.get(key2);
299732
+ const detail = src ? ` from ${src}` : "";
299733
+ console.warn(`[superdoc] font face failed to load: "${request.family}" ${request.weight} ${request.style}${detail}. Check fonts.assetBaseUrl / fonts.resolveAssetUrl so the bundled .woff2 are served.`);
299734
+ }
299735
+ async#loadOne(family$1, timeoutMs) {
299736
+ const fontSet = this.#fontSet;
299737
+ if (!fontSet) {
299738
+ this.#status.set(family$1, "fallback_used");
299739
+ return {
299740
+ family: family$1,
299741
+ status: "fallback_used"
299742
+ };
299743
+ }
299744
+ this.#status.set(family$1, "loading");
299745
+ const probe = `${this.#probeSize} ${quoteFamily(family$1)}`;
299746
+ const TIMEOUT = Symbol("timeout");
299747
+ let handle3;
299748
+ const timeout$1 = new Promise((resolve2) => {
299749
+ handle3 = this.#scheduleTimeout(() => resolve2(TIMEOUT), timeoutMs);
299750
+ });
299751
+ try {
299752
+ const settled = await Promise.race([fontSet.load(probe), timeout$1]);
299753
+ if (settled === TIMEOUT) {
299754
+ this.#status.set(family$1, "timed_out");
299755
+ return {
299756
+ family: family$1,
299757
+ status: "timed_out"
299758
+ };
299759
+ }
299760
+ const status = settled.length > 0 ? "loaded" : "fallback_used";
299761
+ this.#status.set(family$1, status);
299762
+ return {
299763
+ family: family$1,
299764
+ status
299765
+ };
299766
+ } catch {
299767
+ this.#status.set(family$1, "failed");
299768
+ this.#warnLoadFailureOnce(family$1);
299769
+ return {
299770
+ family: family$1,
299771
+ status: "failed"
299772
+ };
299773
+ } finally {
299774
+ this.#cancelTimeout(handle3);
299775
+ }
299776
+ }
299777
+ #warnLoadFailureOnce(family$1) {
299778
+ if (this.#warnedFailures.has(family$1))
299779
+ return;
299780
+ this.#warnedFailures.add(family$1);
299781
+ const sources = this.#sources.get(family$1);
299782
+ const detail = sources && sources.length ? ` from ${sources.join(", ")}` : "";
299783
+ console.warn(`[superdoc] font asset failed to load for "${family$1}"${detail}. Check fonts.assetBaseUrl / fonts.resolveAssetUrl so the bundled .woff2 are served.`);
299784
+ }
299785
+ }, registriesByFontSet, domlessRegistry = null, hashParagraphBorder$2 = (border) => {
299246
299786
  const parts = [];
299247
299787
  if (border.style !== undefined)
299248
299788
  parts.push(`s:${border.style}`);
@@ -299559,7 +300099,7 @@ menclose::after {
299559
300099
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
299560
300100
  return;
299561
300101
  return value;
299562
- }, resolvePainterMarkerTextWidth = (markerTextWidthPx, marker) => getFiniteNonNegativeNumber(markerTextWidthPx) ?? getFiniteNonNegativeNumber(marker.glyphWidthPx) ?? getFiniteNonNegativeNumber(marker.markerBoxWidthPx) ?? 0, resolvePainterListMarkerGeometry = ({ wordLayout, indentLeftPx, hangingIndentPx, firstLineIndentPx, markerTextWidthPx }) => resolveListMarkerGeometry(wordLayout, indentLeftPx, firstLineIndentPx, hangingIndentPx, (_markerText, marker) => resolvePainterMarkerTextWidth(markerTextWidthPx, marker)), resolvePainterListTextStartPx = ({ wordLayout, indentLeftPx, hangingIndentPx, firstLineIndentPx, markerTextWidthPx }) => resolveListTextStartPx(wordLayout, indentLeftPx, firstLineIndentPx, hangingIndentPx, (_markerText, marker) => resolvePainterMarkerTextWidth(markerTextWidthPx, marker)), isMarkerSuffix = (suffix) => suffix === "tab" || suffix === "space" || suffix === "nothing", createListMarkerElement = (doc$12, markerText, run2, sourceAnchor) => {
300102
+ }, resolvePainterMarkerTextWidth = (markerTextWidthPx, marker) => getFiniteNonNegativeNumber(markerTextWidthPx) ?? getFiniteNonNegativeNumber(marker.glyphWidthPx) ?? getFiniteNonNegativeNumber(marker.markerBoxWidthPx) ?? 0, resolvePainterListMarkerGeometry = ({ wordLayout, indentLeftPx, hangingIndentPx, firstLineIndentPx, markerTextWidthPx }) => resolveListMarkerGeometry(wordLayout, indentLeftPx, firstLineIndentPx, hangingIndentPx, (_markerText, marker) => resolvePainterMarkerTextWidth(markerTextWidthPx, marker)), resolvePainterListTextStartPx = ({ wordLayout, indentLeftPx, hangingIndentPx, firstLineIndentPx, markerTextWidthPx }) => resolveListTextStartPx(wordLayout, indentLeftPx, firstLineIndentPx, hangingIndentPx, (_markerText, marker) => resolvePainterMarkerTextWidth(markerTextWidthPx, marker)), isMarkerSuffix = (suffix) => suffix === "tab" || suffix === "space" || suffix === "nothing", createListMarkerElement = (doc$12, markerText, run2, sourceAnchor, resolvePhysical = (css) => resolvePhysicalFamily(css)) => {
299563
300103
  const markerContainer = doc$12.createElement("span");
299564
300104
  markerContainer.classList.add(DOM_CLASS_NAMES.LIST_MARKER);
299565
300105
  markerContainer.style.display = "inline-block";
@@ -299568,7 +300108,11 @@ menclose::after {
299568
300108
  markerEl.classList.add("superdoc-paragraph-marker");
299569
300109
  markerEl.textContent = markerText;
299570
300110
  markerEl.style.pointerEvents = "none";
299571
- markerEl.style.fontFamily = toCssFontFamily(run2.fontFamily) ?? run2.fontFamily ?? "";
300111
+ const cssFontFamily = toCssFontFamily(run2.fontFamily) ?? run2.fontFamily ?? "";
300112
+ markerEl.style.fontFamily = resolvePhysical(cssFontFamily, {
300113
+ weight: run2.bold ? "700" : "400",
300114
+ style: run2.italic ? "italic" : "normal"
300115
+ });
299572
300116
  if (run2.fontSize != null)
299573
300117
  markerEl.style.fontSize = `${run2.fontSize}px`;
299574
300118
  markerEl.style.fontWeight = run2.bold ? "bold" : "";
@@ -299586,7 +300130,7 @@ menclose::after {
299586
300130
  applySourceAnchorDataset(markerEl, sourceAnchor);
299587
300131
  return markerContainer;
299588
300132
  }, renderLegacyListMarker = (params$1) => {
299589
- const { doc: doc$12, lineEl, wordLayout, markerLayout, markerMeasure, markerTextWidthPx, indentLeftPx, hangingIndentPx, firstLineIndentPx, isRtl, sourceAnchor } = params$1;
300133
+ const { doc: doc$12, lineEl, wordLayout, markerLayout, markerMeasure, markerTextWidthPx, indentLeftPx, hangingIndentPx, firstLineIndentPx, isRtl, sourceAnchor, resolvePhysical = (css) => resolvePhysicalFamily(css) } = params$1;
299590
300134
  const markerTextWidth = markerTextWidthPx ?? markerMeasure?.markerTextWidth ?? 0;
299591
300135
  const markerGeometry = markerLayout?.justification === "left" && wordLayout?.firstLineIndentMode !== true && typeof markerTextWidth === "number" && Number.isFinite(markerTextWidth) && markerTextWidth >= 0 ? resolvePainterListMarkerGeometry({
299592
300136
  wordLayout,
@@ -299623,7 +300167,7 @@ menclose::after {
299623
300167
  lineEl.style.paddingLeft = `${anchorPoint}px`;
299624
300168
  if (markerLayout?.run?.vanish)
299625
300169
  return;
299626
- const markerContainer = createListMarkerElement(doc$12, markerLayout?.markerText ?? "", markerLayout?.run ?? {}, sourceAnchor);
300170
+ const markerContainer = createListMarkerElement(doc$12, markerLayout?.markerText ?? "", markerLayout?.run ?? {}, sourceAnchor, resolvePhysical);
299627
300171
  markerContainer.style.position = "relative";
299628
300172
  if (markerJustification === "right") {
299629
300173
  markerContainer.style.position = "absolute";
@@ -299644,14 +300188,14 @@ menclose::after {
299644
300188
  prependMarkerSuffix(doc$12, lineEl, isMarkerSuffix(suffix) ? suffix : undefined, suffixWidthPx, markerLayout?.run?.fontSize);
299645
300189
  lineEl.prepend(markerContainer);
299646
300190
  }, renderResolvedListMarker = (params$1) => {
299647
- const { doc: doc$12, lineEl, marker, isRtl, sourceAnchor } = params$1;
300191
+ const { doc: doc$12, lineEl, marker, isRtl, sourceAnchor, resolvePhysical } = params$1;
299648
300192
  if (isRtl)
299649
300193
  lineEl.style.paddingRight = `${marker.firstLinePaddingLeftPx}px`;
299650
300194
  else
299651
300195
  lineEl.style.paddingLeft = `${marker.firstLinePaddingLeftPx}px`;
299652
300196
  if (marker.vanish)
299653
300197
  return;
299654
- const markerContainer = createListMarkerElement(doc$12, marker.text, marker.run, marker.sourceAnchor ?? sourceAnchor);
300198
+ const markerContainer = createListMarkerElement(doc$12, marker.text, marker.run, marker.sourceAnchor ?? sourceAnchor, resolvePhysical);
299655
300199
  markerContainer.style.position = "relative";
299656
300200
  if (marker.justification === "right") {
299657
300201
  markerContainer.style.position = "absolute";
@@ -299919,7 +300463,7 @@ menclose::after {
299919
300463
  skipJustifyOverride: (resolvedLine?.skipJustify ?? false) || hasMultipleExplicitPositionedSegments
299920
300464
  }) ? Math.max(lineWidth, availableWidth) : lineWidth;
299921
300465
  }, renderResolvedLines = (params$1) => {
299922
- const { frameEl, block, resolvedContent: content3, markerTextWidth, renderLine: renderLine$1, captureLineSnapshot, convertFinalParagraphMark, lineTopOffset = 0, sourceAnchor } = params$1;
300466
+ const { frameEl, block, resolvedContent: content3, markerTextWidth, renderLine: renderLine$1, captureLineSnapshot, convertFinalParagraphMark, lineTopOffset = 0, sourceAnchor, resolvePhysical = (css) => resolvePhysicalFamily(css) } = params$1;
299923
300467
  const renderedLines = [];
299924
300468
  const resolvedMarker = content3.marker;
299925
300469
  const expandedRunsForBlock = expandRunsForInlineNewlines(block.runs);
@@ -299949,7 +300493,8 @@ menclose::after {
299949
300493
  lineEl,
299950
300494
  marker: resolvedMarker,
299951
300495
  isRtl,
299952
- sourceAnchor
300496
+ sourceAnchor,
300497
+ resolvePhysical
299953
300498
  });
299954
300499
  if (convertFinalParagraphMark && index2 === content3.lines.length - 1 && !content3.continuesOnNext)
299955
300500
  convertParagraphMarkToCellMark(lineEl);
@@ -299972,7 +300517,7 @@ menclose::after {
299972
300517
  renderedLines
299973
300518
  };
299974
300519
  }, renderMeasuredLines = (params$1) => {
299975
- const { doc: doc$12, frameEl, block, measure, containerKind, width, localStartLine, localEndLine, linesOverride, lineIndexOffset = 0, continuesFromPrev, continuesOnNext, markerWidth, markerTextWidth, wordLayout, renderLine: renderLine$1, captureLineSnapshot, convertFinalParagraphMark, lineTopOffset = 0, sourceAnchor } = params$1;
300520
+ const { doc: doc$12, frameEl, block, measure, containerKind, width, localStartLine, localEndLine, linesOverride, lineIndexOffset = 0, continuesFromPrev, continuesOnNext, markerWidth, markerTextWidth, wordLayout, renderLine: renderLine$1, captureLineSnapshot, convertFinalParagraphMark, lineTopOffset = 0, sourceAnchor, resolvePhysical = (css) => resolvePhysicalFamily(css) } = params$1;
299976
300521
  const lines = linesOverride ?? measure.lines ?? [];
299977
300522
  const paraIndent = block.attrs?.indent;
299978
300523
  const paraIndentLeft = paraIndent?.left ?? 0;
@@ -300046,7 +300591,8 @@ menclose::after {
300046
300591
  hangingIndentPx: markerHanging,
300047
300592
  firstLineIndentPx: markerFirstLine,
300048
300593
  isRtl,
300049
- sourceAnchor
300594
+ sourceAnchor,
300595
+ resolvePhysical
300050
300596
  });
300051
300597
  } else
300052
300598
  applyParagraphLineIndentation({
@@ -300200,7 +300746,7 @@ menclose::after {
300200
300746
  hasSdtContainerChrome
300201
300747
  };
300202
300748
  }, renderTableCell = (deps) => {
300203
- const { doc: doc$12, x, y: y$1, rowHeight, cellMeasure, cell: cell2, borders, useDefaultBorder, renderLine: renderLine$1, captureLineSnapshot, renderDrawingContent, context, applySdtDataset: applySdtDataset$1, chrome: chrome2, ancestorContainerKey, ancestorContainerSdt, ancestorContainerKeys, ancestorContainerSdts, onSdtContainerChrome, tableIndent, isRtl, cellWidth, fromLine, toLine } = deps;
300749
+ const { doc: doc$12, x, y: y$1, rowHeight, cellMeasure, cell: cell2, borders, useDefaultBorder, renderLine: renderLine$1, captureLineSnapshot, renderDrawingContent, context, applySdtDataset: applySdtDataset$1, chrome: chrome2, ancestorContainerKey, ancestorContainerSdt, ancestorContainerKeys, ancestorContainerSdts, onSdtContainerChrome, tableIndent, isRtl, cellWidth, fromLine, toLine, resolvePhysical } = deps;
300204
300750
  const padding = cell2?.attrs?.padding || {
300205
300751
  top: 0,
300206
300752
  left: 4,
@@ -300452,6 +300998,7 @@ menclose::after {
300452
300998
  },
300453
300999
  contentControlsChrome: chrome2,
300454
301000
  applySdtDataset: applySdtDataset$1,
301001
+ resolvePhysical,
300455
301002
  renderLine: ({ block: block$1, line, lineIndex, isLastLine, resolvedListTextStartPx }) => renderLine$1(block$1, line, {
300456
301003
  ...context,
300457
301004
  section: "body"
@@ -300628,7 +301175,7 @@ menclose::after {
300628
301175
  left: baseBorders.left
300629
301176
  };
300630
301177
  }, renderTableRow = (deps) => {
300631
- const { doc: doc$12, container, rowIndex, y: y$1, rowMeasure, row: row2, totalRows, tableBorders, columnWidths, allRowHeights, tableIndent, isRtl, context, renderLine: renderLine$1, captureLineSnapshot, renderDrawingContent, applySdtDataset: applySdtDataset$1, ancestorContainerKey, ancestorContainerSdt, ancestorContainerKeys, ancestorContainerSdts, onSdtContainerChrome, continuesFromPrev, continuesOnNext, partialRow, cellSpacingPx = 0, chrome: chrome2 } = deps;
301178
+ const { doc: doc$12, container, rowIndex, y: y$1, rowMeasure, row: row2, totalRows, tableBorders, columnWidths, allRowHeights, tableIndent, isRtl, context, renderLine: renderLine$1, captureLineSnapshot, renderDrawingContent, applySdtDataset: applySdtDataset$1, ancestorContainerKey, ancestorContainerSdt, ancestorContainerKeys, ancestorContainerSdts, onSdtContainerChrome, continuesFromPrev, continuesOnNext, partialRow, cellSpacingPx = 0, chrome: chrome2, resolvePhysical } = deps;
300632
301179
  const totalCols = columnWidths.length;
300633
301180
  const calculateXPosition = (gridColumnStart) => {
300634
301181
  let x = cellSpacingPx;
@@ -300715,12 +301262,13 @@ menclose::after {
300715
301262
  tableIndent,
300716
301263
  isRtl,
300717
301264
  cellWidth: computedCellWidth > 0 ? computedCellWidth : undefined,
300718
- chrome: chrome2
301265
+ chrome: chrome2,
301266
+ resolvePhysical
300719
301267
  });
300720
301268
  container.appendChild(cellElement);
300721
301269
  }
300722
301270
  }, renderTableFragment = (deps) => {
300723
- const { doc: doc$12, fragment, block, measure, cellSpacingPx, effectiveColumnWidths, chrome: chrome2, context, sdtBoundary, ancestorContainerKey, ancestorContainerSdt, ancestorContainerKeys, ancestorContainerSdts, onSdtContainerChrome, renderLine: renderLine$1, captureLineSnapshot, renderDrawingContent, applyFragmentFrame, applySdtDataset: applySdtDataset$1, applyContainerSdtDataset: applyContainerSdtDataset$1, applyStyles: applyStyles$3 } = deps;
301271
+ const { doc: doc$12, fragment, block, measure, cellSpacingPx, effectiveColumnWidths, chrome: chrome2, context, sdtBoundary, ancestorContainerKey, ancestorContainerSdt, ancestorContainerKeys, ancestorContainerSdts, onSdtContainerChrome, renderLine: renderLine$1, captureLineSnapshot, renderDrawingContent, applyFragmentFrame, applySdtDataset: applySdtDataset$1, applyContainerSdtDataset: applyContainerSdtDataset$1, applyStyles: applyStyles$3, resolvePhysical } = deps;
300724
301272
  if (!doc$12) {
300725
301273
  console.error("DomPainter: document is not available");
300726
301274
  if (typeof document !== "undefined") {
@@ -300902,7 +301450,8 @@ menclose::after {
300902
301450
  chrome: chrome2,
300903
301451
  continuesFromPrev: false,
300904
301452
  continuesOnNext: false,
300905
- cellSpacingPx
301453
+ cellSpacingPx,
301454
+ resolvePhysical
300906
301455
  });
300907
301456
  y$1 += rowMeasure.height + cellSpacingPx;
300908
301457
  }
@@ -301020,7 +301569,8 @@ menclose::after {
301020
301569
  continuesFromPrev: isFirstRenderedBodyRow && fragment.continuesFromPrev === true,
301021
301570
  continuesOnNext: isLastRenderedBodyRow && fragment.continuesOnNext === true,
301022
301571
  partialRow: partialRowData,
301023
- cellSpacingPx
301572
+ cellSpacingPx,
301573
+ resolvePhysical
301024
301574
  });
301025
301575
  y$1 += actualRowHeight + cellSpacingPx;
301026
301576
  }
@@ -301238,7 +301788,7 @@ menclose::after {
301238
301788
  else
301239
301789
  delete el.dataset.continuesOnNext;
301240
301790
  }, isMinimalWordLayout$2 = (value) => isMinimalWordLayout(value), renderParagraphFragment = (params$1) => {
301241
- const { doc: doc$12, fragment, sdtBoundary, betweenInfo, resolvedItem, applyStyles: applyStyles$3, applyResolvedFragmentFrame, applyFragmentFrame, applySdtDataset: applySdtDataset$1, applyContainerSdtDataset: applyContainerSdtDataset$1, renderLine: renderLine$1, captureLineSnapshot, createErrorPlaceholder, contentControlsChrome } = params$1;
301791
+ const { doc: doc$12, fragment, sdtBoundary, betweenInfo, resolvedItem, applyStyles: applyStyles$3, applyResolvedFragmentFrame, applyFragmentFrame, applySdtDataset: applySdtDataset$1, applyContainerSdtDataset: applyContainerSdtDataset$1, renderLine: renderLine$1, captureLineSnapshot, createErrorPlaceholder, contentControlsChrome, resolvePhysical = (css) => resolvePhysicalFamily(css) } = params$1;
301242
301792
  try {
301243
301793
  if (!doc$12)
301244
301794
  throw new Error("DomPainter: document is not available");
@@ -301297,7 +301847,8 @@ menclose::after {
301297
301847
  sdtBoundary,
301298
301848
  applySdtDataset: applySdtDataset$1,
301299
301849
  applyContainerSdtDataset: applyContainerSdtDataset$1,
301300
- renderDropCap: (descriptor, dropCapMeasure) => renderDropCap(doc$12, descriptor, dropCapMeasure),
301850
+ resolvePhysical,
301851
+ renderDropCap: (descriptor, dropCapMeasure) => renderDropCap(doc$12, descriptor, dropCapMeasure, resolvePhysical),
301301
301852
  renderLine: renderLine$1,
301302
301853
  captureLineSnapshot: (lineEl, options) => {
301303
301854
  captureLineSnapshot(lineEl, {
@@ -301316,12 +301867,15 @@ menclose::after {
301316
301867
  });
301317
301868
  return createErrorPlaceholder(fragment.blockId, error48);
301318
301869
  }
301319
- }, renderDropCap = (doc$12, descriptor, measure) => {
301870
+ }, renderDropCap = (doc$12, descriptor, measure, resolvePhysical = (css) => resolvePhysicalFamily(css)) => {
301320
301871
  const { run: run2, mode } = descriptor;
301321
301872
  const dropCapEl = doc$12.createElement("span");
301322
301873
  dropCapEl.classList.add("superdoc-drop-cap");
301323
301874
  dropCapEl.textContent = run2.text;
301324
- dropCapEl.style.fontFamily = run2.fontFamily;
301875
+ dropCapEl.style.fontFamily = resolvePhysical(run2.fontFamily, {
301876
+ weight: run2.bold ? "700" : "400",
301877
+ style: run2.italic ? "italic" : "normal"
301878
+ });
301325
301879
  dropCapEl.style.fontSize = `${run2.fontSize}px`;
301326
301880
  if (run2.bold)
301327
301881
  dropCapEl.style.fontWeight = "bold";
@@ -301414,344 +301968,7 @@ menclose::after {
301414
301968
  const visualTextEndOffset = lineEl.dir === "rtl" || lineEl.style.direction === "rtl" ? alignmentOffset : alignmentOffset + lineWidth;
301415
301969
  mark2.style.left = `${Math.max(0, leftOffsetPx + visualTextEndOffset)}px`;
301416
301970
  lineEl.appendChild(mark2);
301417
- }, SETTLED_STATUSES, BUNDLED_SUBSTITUTES, FontResolver = class {
301418
- #overrides = /* @__PURE__ */ new Map;
301419
- #version = 0;
301420
- map(logicalFamily, physicalFamily) {
301421
- const key2 = normalizeFamilyKey$2(logicalFamily);
301422
- const physical = physicalFamily?.trim();
301423
- if (!key2 || !physical)
301424
- return;
301425
- if (this.#overrides.get(key2) === physical)
301426
- return;
301427
- this.#overrides.set(key2, physical);
301428
- this.#version += 1;
301429
- }
301430
- unmap(logicalFamily) {
301431
- if (this.#overrides.delete(normalizeFamilyKey$2(logicalFamily)))
301432
- this.#version += 1;
301433
- }
301434
- reset() {
301435
- if (this.#overrides.size === 0)
301436
- return;
301437
- this.#overrides.clear();
301438
- this.#version += 1;
301439
- }
301440
- get version() {
301441
- return this.#version;
301442
- }
301443
- get signature() {
301444
- if (this.#overrides.size === 0)
301445
- return "";
301446
- return JSON.stringify([...this.#overrides.entries()].sort(([a2], [b$1]) => a2 < b$1 ? -1 : a2 > b$1 ? 1 : 0));
301447
- }
301448
- #physicalFor(bareFamily) {
301449
- const key2 = normalizeFamilyKey$2(bareFamily);
301450
- const override = this.#overrides.get(key2);
301451
- if (override)
301452
- return {
301453
- physical: override,
301454
- reason: "custom_mapping"
301455
- };
301456
- const bundled = BUNDLED_SUBSTITUTES[key2];
301457
- if (bundled)
301458
- return {
301459
- physical: bundled,
301460
- reason: "bundled_substitute"
301461
- };
301462
- return {
301463
- physical: bareFamily,
301464
- reason: "as_requested"
301465
- };
301466
- }
301467
- resolveFontFamily(logicalFamily) {
301468
- const primary = splitStack(logicalFamily)[0] ?? logicalFamily;
301469
- const { physical, reason } = this.#physicalFor(primary);
301470
- return {
301471
- logicalFamily,
301472
- physicalFamily: physical,
301473
- reason
301474
- };
301475
- }
301476
- resolvePhysicalFamily(cssFontFamily) {
301477
- if (!cssFontFamily)
301478
- return cssFontFamily;
301479
- const parts = splitStack(cssFontFamily);
301480
- if (parts.length === 0)
301481
- return cssFontFamily;
301482
- const { physical, reason } = this.#physicalFor(parts[0]);
301483
- if (reason === "as_requested")
301484
- return cssFontFamily;
301485
- return [physical, ...parts.slice(1)].join(", ");
301486
- }
301487
- resolvePrimaryPhysicalFamily(family$1) {
301488
- const primary = splitStack(family$1)[0] ?? family$1;
301489
- return this.#physicalFor(primary).physical;
301490
- }
301491
- resolvePhysicalFamilies(families) {
301492
- const out = /* @__PURE__ */ new Set;
301493
- for (const family$1 of families)
301494
- if (family$1)
301495
- out.add(this.resolvePrimaryPhysicalFamily(family$1));
301496
- return [...out];
301497
- }
301498
- }, defaultResolver, fontConfigVersion = 0, BUNDLED_MANIFEST, defaultAssetBase = "/fonts/", installedRegistries, DEFAULT_FONT_LOAD_TIMEOUT_MS = 3000, DEFAULT_PROBE_SIZE = "16px", FontRegistry = class {
301499
- #fontSet;
301500
- #FontFaceCtor;
301501
- #probeSize;
301502
- #scheduleTimeout;
301503
- #cancelTimeout;
301504
- #managed = /* @__PURE__ */ new Map;
301505
- #status = /* @__PURE__ */ new Map;
301506
- #sources = /* @__PURE__ */ new Map;
301507
- #warnedFailures = /* @__PURE__ */ new Set;
301508
- #inflight = /* @__PURE__ */ new Map;
301509
- #faceStatus = /* @__PURE__ */ new Map;
301510
- #faceInflight = /* @__PURE__ */ new Map;
301511
- #faceSources = /* @__PURE__ */ new Map;
301512
- #facesByFamily = /* @__PURE__ */ new Map;
301513
- #warnedFaceFailures = /* @__PURE__ */ new Set;
301514
- constructor(options = {}) {
301515
- this.#fontSet = options.fontSet ?? null;
301516
- this.#FontFaceCtor = options.FontFaceCtor ?? null;
301517
- this.#probeSize = options.probeSize ?? DEFAULT_PROBE_SIZE;
301518
- this.#scheduleTimeout = options.scheduleTimeout ?? ((cb, ms) => globalThis.setTimeout(cb, ms));
301519
- this.#cancelTimeout = options.cancelTimeout ?? ((handle3) => globalThis.clearTimeout(handle3));
301520
- }
301521
- register(descriptor) {
301522
- const { family: family$1, source, descriptors: descriptors2 } = descriptor;
301523
- if (this.#FontFaceCtor && this.#fontSet) {
301524
- const face = new this.#FontFaceCtor(family$1, source, descriptors2);
301525
- this.#fontSet.add(face);
301526
- this.#managed.set(family$1, face);
301527
- }
301528
- if (typeof source === "string") {
301529
- const list5 = this.#sources.get(family$1) ?? [];
301530
- if (!list5.includes(source))
301531
- list5.push(source);
301532
- this.#sources.set(family$1, list5);
301533
- }
301534
- if (!this.#status.has(family$1))
301535
- this.#status.set(family$1, "unloaded");
301536
- const key2 = faceKeyOf$1(family$1, normalizeWeight(descriptors2?.weight), normalizeStyle$1(descriptors2?.style));
301537
- this.#trackFace(family$1, key2);
301538
- if (!this.#faceStatus.has(key2))
301539
- this.#faceStatus.set(key2, "unloaded");
301540
- if (typeof source === "string" && !this.#faceSources.has(key2))
301541
- this.#faceSources.set(key2, source);
301542
- return {
301543
- family: family$1,
301544
- status: this.getStatus(family$1)
301545
- };
301546
- }
301547
- #trackFace(family$1, key2) {
301548
- const fam = normalizeFamilyKey$1(family$1);
301549
- const set3 = this.#facesByFamily.get(fam) ?? /* @__PURE__ */ new Set;
301550
- set3.add(key2);
301551
- this.#facesByFamily.set(fam, set3);
301552
- }
301553
- isManaged(family$1) {
301554
- return this.#managed.has(family$1);
301555
- }
301556
- getStatus(family$1) {
301557
- const statuses = [];
301558
- const faceKeys = this.#facesByFamily.get(normalizeFamilyKey$1(family$1));
301559
- if (faceKeys)
301560
- for (const k$1 of faceKeys)
301561
- statuses.push(this.#faceStatus.get(k$1) ?? "unloaded");
301562
- const legacy = this.#status.get(family$1);
301563
- if (legacy)
301564
- statuses.push(legacy);
301565
- if (statuses.length === 0)
301566
- return "unloaded";
301567
- for (const s2 of [
301568
- "failed",
301569
- "timed_out",
301570
- "fallback_used",
301571
- "loaded",
301572
- "loading",
301573
- "unloaded"
301574
- ])
301575
- if (statuses.includes(s2))
301576
- return s2;
301577
- return "unloaded";
301578
- }
301579
- isAvailable(family$1) {
301580
- if (!this.#fontSet)
301581
- return false;
301582
- try {
301583
- return this.#fontSet.check(`${this.#probeSize} ${quoteFamily(family$1)}`);
301584
- } catch {
301585
- return false;
301586
- }
301587
- }
301588
- awaitFace(family$1, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
301589
- if (this.#status.get(family$1) === "loaded")
301590
- return Promise.resolve({
301591
- family: family$1,
301592
- status: "loaded"
301593
- });
301594
- const existing = this.#inflight.get(family$1);
301595
- if (existing)
301596
- return existing;
301597
- const probe = this.#loadOne(family$1, timeoutMs).finally(() => {
301598
- this.#inflight.delete(family$1);
301599
- });
301600
- this.#inflight.set(family$1, probe);
301601
- return probe;
301602
- }
301603
- async awaitFaces(families, options = {}) {
301604
- const unique$2 = [...new Set(families)];
301605
- const timeoutMs = options.timeoutMs ?? 3000;
301606
- return Promise.all(unique$2.map((family$1) => this.awaitFace(family$1, timeoutMs)));
301607
- }
301608
- getRequiredFaces(families, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
301609
- return [...new Set(families)].map((family$1) => ({
301610
- family: family$1,
301611
- status: this.getStatus(family$1),
301612
- ready: this.awaitFace(family$1, timeoutMs)
301613
- }));
301614
- }
301615
- getStates() {
301616
- return [...this.#status.entries()].map(([family$1, status]) => ({
301617
- family: family$1,
301618
- status
301619
- }));
301620
- }
301621
- getFaceStatus(request) {
301622
- return this.#faceStatus.get(faceKeyOf$1(request.family, request.weight, request.style)) ?? "unloaded";
301623
- }
301624
- awaitFaceRequest(request, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
301625
- const key2 = faceKeyOf$1(request.family, request.weight, request.style);
301626
- if (this.#faceStatus.get(key2) === "loaded")
301627
- return Promise.resolve({
301628
- request,
301629
- status: "loaded"
301630
- });
301631
- const existing = this.#faceInflight.get(key2);
301632
- if (existing)
301633
- return existing;
301634
- const probe = this.#loadOneFace(request, key2, timeoutMs).finally(() => {
301635
- this.#faceInflight.delete(key2);
301636
- });
301637
- this.#faceInflight.set(key2, probe);
301638
- return probe;
301639
- }
301640
- async awaitFaceRequests(requests, options = {}) {
301641
- const timeoutMs = options.timeoutMs ?? 3000;
301642
- const seen = /* @__PURE__ */ new Set;
301643
- const unique$2 = [];
301644
- for (const r$1 of requests) {
301645
- const key2 = faceKeyOf$1(r$1.family, r$1.weight, r$1.style);
301646
- if (seen.has(key2))
301647
- continue;
301648
- seen.add(key2);
301649
- unique$2.push(r$1);
301650
- }
301651
- return Promise.all(unique$2.map((r$1) => this.awaitFaceRequest(r$1, timeoutMs)));
301652
- }
301653
- async#loadOneFace(request, key2, timeoutMs) {
301654
- this.#trackFace(request.family, key2);
301655
- const fontSet = this.#fontSet;
301656
- if (!fontSet) {
301657
- this.#faceStatus.set(key2, "fallback_used");
301658
- return {
301659
- request,
301660
- status: "fallback_used"
301661
- };
301662
- }
301663
- this.#faceStatus.set(key2, "loading");
301664
- const probe = faceProbe(request.family, request.weight, request.style, this.#probeSize);
301665
- const TIMEOUT = Symbol("timeout");
301666
- let handle3;
301667
- const timeout$1 = new Promise((resolve2) => {
301668
- handle3 = this.#scheduleTimeout(() => resolve2(TIMEOUT), timeoutMs);
301669
- });
301670
- try {
301671
- const settled = await Promise.race([fontSet.load(probe), timeout$1]);
301672
- if (settled === TIMEOUT) {
301673
- this.#faceStatus.set(key2, "timed_out");
301674
- return {
301675
- request,
301676
- status: "timed_out"
301677
- };
301678
- }
301679
- const status = settled.length > 0 ? "loaded" : "fallback_used";
301680
- this.#faceStatus.set(key2, status);
301681
- return {
301682
- request,
301683
- status
301684
- };
301685
- } catch {
301686
- this.#faceStatus.set(key2, "failed");
301687
- this.#warnFaceFailureOnce(request, key2);
301688
- return {
301689
- request,
301690
- status: "failed"
301691
- };
301692
- } finally {
301693
- this.#cancelTimeout(handle3);
301694
- }
301695
- }
301696
- #warnFaceFailureOnce(request, key2) {
301697
- if (this.#warnedFaceFailures.has(key2))
301698
- return;
301699
- this.#warnedFaceFailures.add(key2);
301700
- const src = this.#faceSources.get(key2);
301701
- const detail = src ? ` from ${src}` : "";
301702
- console.warn(`[superdoc] font face failed to load: "${request.family}" ${request.weight} ${request.style}${detail}. Check fonts.assetBaseUrl / fonts.resolveAssetUrl so the bundled .woff2 are served.`);
301703
- }
301704
- async#loadOne(family$1, timeoutMs) {
301705
- const fontSet = this.#fontSet;
301706
- if (!fontSet) {
301707
- this.#status.set(family$1, "fallback_used");
301708
- return {
301709
- family: family$1,
301710
- status: "fallback_used"
301711
- };
301712
- }
301713
- this.#status.set(family$1, "loading");
301714
- const probe = `${this.#probeSize} ${quoteFamily(family$1)}`;
301715
- const TIMEOUT = Symbol("timeout");
301716
- let handle3;
301717
- const timeout$1 = new Promise((resolve2) => {
301718
- handle3 = this.#scheduleTimeout(() => resolve2(TIMEOUT), timeoutMs);
301719
- });
301720
- try {
301721
- const settled = await Promise.race([fontSet.load(probe), timeout$1]);
301722
- if (settled === TIMEOUT) {
301723
- this.#status.set(family$1, "timed_out");
301724
- return {
301725
- family: family$1,
301726
- status: "timed_out"
301727
- };
301728
- }
301729
- const status = settled.length > 0 ? "loaded" : "fallback_used";
301730
- this.#status.set(family$1, status);
301731
- return {
301732
- family: family$1,
301733
- status
301734
- };
301735
- } catch {
301736
- this.#status.set(family$1, "failed");
301737
- this.#warnLoadFailureOnce(family$1);
301738
- return {
301739
- family: family$1,
301740
- status: "failed"
301741
- };
301742
- } finally {
301743
- this.#cancelTimeout(handle3);
301744
- }
301745
- }
301746
- #warnLoadFailureOnce(family$1) {
301747
- if (this.#warnedFailures.has(family$1))
301748
- return;
301749
- this.#warnedFailures.add(family$1);
301750
- const sources = this.#sources.get(family$1);
301751
- const detail = sources && sources.length ? ` from ${sources.join(", ")}` : "";
301752
- console.warn(`[superdoc] font asset failed to load for "${family$1}"${detail}. Check fonts.assetBaseUrl / fonts.resolveAssetUrl so the bundled .woff2 are served.`);
301753
- }
301754
- }, registriesByFontSet, domlessRegistry = null, DEFAULT_SUPERSCRIPT_RAISE_RATIO = 0.33, DEFAULT_SUBSCRIPT_LOWER_RATIO = 0.14, underlineThicknessPx = (fontSize) => Math.max(1, Math.round(fontSize / 14)), hasVerticalPositioning = (run2) => normalizeBaselineShift(run2.baselineShift) != null || run2.vertAlign === "superscript" || run2.vertAlign === "subscript", applyRunVerticalPositioning = (element3, run2) => {
301971
+ }, DEFAULT_SUPERSCRIPT_RAISE_RATIO = 0.33, DEFAULT_SUBSCRIPT_LOWER_RATIO = 0.14, underlineThicknessPx = (fontSize) => Math.max(1, Math.round(fontSize / 14)), hasVerticalPositioning = (run2) => normalizeBaselineShift(run2.baselineShift) != null || run2.vertAlign === "superscript" || run2.vertAlign === "subscript", applyRunVerticalPositioning = (element3, run2) => {
301755
301972
  if (hasVerticalPositioning(run2))
301756
301973
  element3.style.lineHeight = "1";
301757
301974
  const explicitBaselineShift = normalizeBaselineShift(run2.baselineShift);
@@ -301774,7 +301991,10 @@ menclose::after {
301774
301991
  }, applyRunStyles = (element3, run2, _isLink = false, resolvePhysical = resolvePhysicalFamily) => {
301775
301992
  if (run2.kind === "tab" || run2.kind === "image" || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" || run2.kind === "math")
301776
301993
  return;
301777
- element3.style.fontFamily = resolvePhysical(run2.fontFamily);
301994
+ element3.style.fontFamily = resolvePhysical(run2.fontFamily, {
301995
+ weight: run2.bold ? "700" : "400",
301996
+ style: run2.italic ? "italic" : "normal"
301997
+ });
301778
301998
  element3.style.fontSize = `${run2.fontSize}px`;
301779
301999
  if (run2.bold)
301780
302000
  element3.style.fontWeight = "bold";
@@ -301955,8 +302175,13 @@ menclose::after {
301955
302175
  annotation.style.height = `${run2.size.height}px`;
301956
302176
  }
301957
302177
  }
301958
- if (run2.fontFamily)
301959
- annotation.style.fontFamily = run2.fontFamily;
302178
+ {
302179
+ const resolvePhysical = context.resolvePhysical ?? resolvePhysicalFamily;
302180
+ annotation.style.fontFamily = resolvePhysical(run2.fontFamily || "Arial, sans-serif", {
302181
+ weight: run2.bold ? "700" : "400",
302182
+ style: run2.italic ? "italic" : "normal"
302183
+ });
302184
+ }
301960
302185
  {
301961
302186
  const fontSize = run2.fontSize ? typeof run2.fontSize === "number" ? `${run2.fontSize}pt` : run2.fontSize : BROWSER_DEFAULT_FONT_SIZE;
301962
302187
  annotation.style.fontSize = fontSize;
@@ -304667,6 +304892,7 @@ menclose::after {
304667
304892
  applyFragmentFrame: (el, paraFragment) => this.applyFragmentFrame(el, paraFragment, context.section, context.story),
304668
304893
  applySdtDataset,
304669
304894
  applyContainerSdtDataset,
304895
+ resolvePhysical: this.options.resolvePhysical,
304670
304896
  renderLine: ({ block, line, availableWidth, lineIndex, skipJustify, preExpandedRuns, resolvedListTextStartPx, indentOffsetOverride, paragraphMarkLeftOffsetOverride }) => this.renderLine(block, line, context, availableWidth, lineIndex, skipJustify, preExpandedRuns, resolvedListTextStartPx, indentOffsetOverride, paragraphMarkLeftOffsetOverride),
304671
304897
  captureLineSnapshot: (lineEl, options) => {
304672
304898
  this.capturePaintSnapshotLine(lineEl, context, {
@@ -305439,7 +305665,8 @@ menclose::after {
305439
305665
  applyFragmentFrame: applyFragmentFrameWithSection,
305440
305666
  applySdtDataset,
305441
305667
  applyContainerSdtDataset,
305442
- applyStyles
305668
+ applyStyles,
305669
+ resolvePhysical: this.options.resolvePhysical
305443
305670
  });
305444
305671
  if (resolvedItem) {
305445
305672
  this.applyResolvedFragmentFrame(el, resolvedItem, fragment, context.section, context.story);
@@ -312915,14 +313142,14 @@ menclose::after {
312915
313142
  if (value === ",")
312916
313143
  return ",";
312917
313144
  return DEFAULT_DECIMAL_SEPARATOR2;
312918
- }, DROP_CAP_PADDING_PX = 4, measureDropCap = (ctx$1, descriptor, spacing, resolvePhysical = resolvePhysicalFamily) => {
313145
+ }, DROP_CAP_PADDING_PX = 4, measureDropCap = (ctx$1, descriptor, spacing, fontContext) => {
312919
313146
  const { run: run2, lines, mode } = descriptor;
312920
313147
  const { font } = buildFontString({
312921
313148
  fontFamily: run2.fontFamily,
312922
313149
  fontSize: run2.fontSize,
312923
313150
  bold: run2.bold,
312924
313151
  italic: run2.italic
312925
- }, resolvePhysical);
313152
+ }, fontContext);
312926
313153
  ctx$1.font = font;
312927
313154
  const displayText = applyTextTransform(run2.text, run2);
312928
313155
  const metrics = ctx$1.measureText(displayText);
@@ -313885,11 +314112,11 @@ menclose::after {
313885
314112
  #resolveResult(result, storyId) {
313886
314113
  return resolveResult(result, storyId, this.#options.getFontSignature?.() ?? "");
313887
314114
  }
313888
- async layoutPerRId(headerFooterInput, layout, sectionMetadata, fontResolver) {
314115
+ async layoutPerRId(headerFooterInput, layout, sectionMetadata, fontResolver, hasFace, effectiveSignature) {
313889
314116
  await layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, {
313890
314117
  headerLayoutsByRId: this.#headerLayoutsByRId,
313891
314118
  footerLayoutsByRId: this.#footerLayoutsByRId
313892
- }, fontResolver);
314119
+ }, fontResolver, hasFace, effectiveSignature);
313893
314120
  this.#resolvedHeaderByRId.clear();
313894
314121
  for (const [key2, result] of this.#headerLayoutsByRId)
313895
314122
  this.#resolvedHeaderByRId.set(key2, this.#resolveResult(result, storyIdFromHeaderFooterLayoutKey(key2)));
@@ -314747,6 +314974,7 @@ menclose::after {
314747
314974
  }, FontReadinessGate = class {
314748
314975
  #getDocumentFonts;
314749
314976
  #getRequiredFaces;
314977
+ #getUsedFaces;
314750
314978
  #resolveFamilies;
314751
314979
  #fontResolver;
314752
314980
  #requestReflow;
@@ -314756,6 +314984,7 @@ menclose::after {
314756
314984
  #timeoutMs;
314757
314985
  #invalidateCaches;
314758
314986
  #context = null;
314987
+ #packInstalledFor = null;
314759
314988
  #fontConfigVersion = 0;
314760
314989
  #requiredSignature = "";
314761
314990
  #requiredFamilies = /* @__PURE__ */ new Set;
@@ -314768,6 +314997,7 @@ menclose::after {
314768
314997
  constructor(options) {
314769
314998
  this.#getDocumentFonts = options.getDocumentFonts;
314770
314999
  this.#getRequiredFaces = options.getRequiredFaces ?? null;
315000
+ this.#getUsedFaces = options.getUsedFaces ?? null;
314771
315001
  this.#fontResolver = options.fontResolver ?? null;
314772
315002
  const resolver2 = this.#fontResolver;
314773
315003
  this.#resolveFamilies = options.resolveFamilies ?? (resolver2 ? (families) => resolver2.resolvePhysicalFamilies(families) : (families) => families);
@@ -314792,13 +315022,19 @@ menclose::after {
314792
315022
  return this.#lastSummary;
314793
315023
  }
314794
315024
  getReport() {
314795
- let logical = [];
315025
+ let declared = [];
314796
315026
  try {
314797
- logical = this.#getDocumentFonts();
315027
+ declared = this.#getDocumentFonts();
314798
315028
  } catch {
314799
315029
  return [];
314800
315030
  }
314801
- return buildFontReport(logical, this.#resolveContext().registry, this.#fontResolver ?? undefined);
315031
+ const registry3 = this.#resolveContext().registry;
315032
+ const resolver2 = this.#fontResolver ?? undefined;
315033
+ const usedFaces = this.#getUsedFaces?.() ?? [];
315034
+ const faceRows = buildFaceReport(usedFaces, registry3, resolver2);
315035
+ const usedFamilies = new Set(usedFaces.map((u) => u.logicalFamily.toLowerCase()));
315036
+ const declaredRows = buildFontReport(declared.filter((family$1) => family$1 && !usedFamilies.has(family$1.toLowerCase())), registry3, resolver2);
315037
+ return [...faceRows, ...declaredRows];
314802
315038
  }
314803
315039
  async ensureReadyForMeasure() {
314804
315040
  if (this.#getRequiredFaces)
@@ -314863,14 +315099,22 @@ menclose::after {
314863
315099
  this.#lastSummary = summarize(results);
314864
315100
  return this.#lastSummary;
314865
315101
  }
314866
- notifyFontConfigChanged() {
315102
+ notifyDocumentFontConfigChanged(options) {
314867
315103
  this.#fontConfigVersion += 1;
314868
- bumpFontConfigVersion();
314869
315104
  this.#resetRequiredAndSeen();
314870
315105
  this.#lateLoadScheduler.cancel();
314871
- this.#invalidateCaches();
315106
+ if (options?.availabilityChanged) {
315107
+ bumpFontConfigVersion();
315108
+ this.#invalidateCaches();
315109
+ }
314872
315110
  this.#requestReflow();
314873
315111
  }
315112
+ invalidateCachesForConfigRegistration() {
315113
+ this.#invalidateCaches();
315114
+ }
315115
+ resolveRegistry() {
315116
+ return this.#resolveContext().registry;
315117
+ }
314874
315118
  resetForDocumentChange() {
314875
315119
  this.#lateLoadScheduler.cancel();
314876
315120
  this.#resetRequiredAndSeen();
@@ -314900,10 +315144,12 @@ menclose::after {
314900
315144
  fontSet,
314901
315145
  registry: registry3
314902
315146
  };
314903
- if (fontSet && this.#onRegistryResolved)
315147
+ if (this.#onRegistryResolved && registry3 !== this.#packInstalledFor) {
315148
+ this.#packInstalledFor = registry3;
314904
315149
  try {
314905
315150
  this.#onRegistryResolved(registry3);
314906
315151
  } catch {}
315152
+ }
314907
315153
  return this.#context;
314908
315154
  }
314909
315155
  #ensureSubscribed() {
@@ -314952,7 +315198,139 @@ menclose::after {
314952
315198
  #flushLateFontLoads() {
314953
315199
  this.#requestReflow();
314954
315200
  }
314955
- }, FACE_STATUS_PRIORITY, DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE, NATIVE_SELECTION_STYLES = `
315201
+ }, FACE_STATUS_PRIORITY, DocumentFontController = class {
315202
+ #resolver;
315203
+ #getGate;
315204
+ #onDocumentFontConfigApplied;
315205
+ #scheduleMicrotask;
315206
+ #runtimeReflowQueued = false;
315207
+ #runtimeReflowToken = 0;
315208
+ #runtimeAvailabilityChanged = false;
315209
+ constructor(deps) {
315210
+ this.#resolver = deps.resolver;
315211
+ this.#getGate = deps.getGate;
315212
+ this.#onDocumentFontConfigApplied = deps.onDocumentFontConfigApplied;
315213
+ this.#scheduleMicrotask = deps.scheduleMicrotask ?? defaultScheduleMicrotask;
315214
+ }
315215
+ map(mappings) {
315216
+ if (this.#applyMappings(mappings))
315217
+ this.#queueRuntimeReflow();
315218
+ }
315219
+ unmap(families) {
315220
+ const before = this.#resolver.signature;
315221
+ for (const family$1 of Array.isArray(families) ? families : [families])
315222
+ this.#resolver.unmap(family$1);
315223
+ this.#reflowIfChanged(before);
315224
+ }
315225
+ reset() {
315226
+ this.#cancelPendingRuntimeReflow();
315227
+ this.#resolver.reset();
315228
+ }
315229
+ dispose() {
315230
+ this.#cancelPendingRuntimeReflow();
315231
+ }
315232
+ applyInitialConfig(config3) {
315233
+ this.#cancelPendingRuntimeReflow();
315234
+ if (!config3)
315235
+ return;
315236
+ const registered$1 = this.#registerFamilies(config3.families);
315237
+ this.#applyMappings(config3.map);
315238
+ if (registered$1)
315239
+ this.#getGate()?.invalidateCachesForConfigRegistration();
315240
+ }
315241
+ add(families) {
315242
+ let committed = false;
315243
+ try {
315244
+ this.#registerFamilies(families, () => {
315245
+ committed = true;
315246
+ });
315247
+ } finally {
315248
+ if (committed) {
315249
+ this.#runtimeAvailabilityChanged = true;
315250
+ this.#queueRuntimeReflow();
315251
+ }
315252
+ }
315253
+ }
315254
+ #registerFamilies(families, onFaceRegistered) {
315255
+ if (!families?.length)
315256
+ return false;
315257
+ const registry3 = this.#getGate()?.resolveRegistry();
315258
+ if (!registry3)
315259
+ throw new Error("[superdoc] fonts.add: the font registry is not ready yet");
315260
+ let changed = false;
315261
+ for (const entry of families) {
315262
+ const family$1 = entry?.family;
315263
+ const faces = entry?.faces;
315264
+ if (typeof family$1 !== "string" || !family$1.trim())
315265
+ throw new Error('[superdoc] fonts.add: each family needs a non-empty "family" name');
315266
+ if (!Array.isArray(faces) || faces.length === 0)
315267
+ throw new Error(`[superdoc] fonts.add: family "${family$1}" needs at least one face in "faces"`);
315268
+ for (const face of faces) {
315269
+ if (!face || typeof face.source !== "string" || !face.source.trim())
315270
+ throw new Error(`[superdoc] fonts.add: family "${family$1}" has a face with no "source" URL`);
315271
+ if (registry3.register({
315272
+ family: family$1,
315273
+ source: toCssFontSource(face.source),
315274
+ descriptors: {
315275
+ weight: face.weight == null ? undefined : String(face.weight),
315276
+ style: face.style
315277
+ }
315278
+ }).changed) {
315279
+ changed = true;
315280
+ onFaceRegistered?.();
315281
+ }
315282
+ }
315283
+ }
315284
+ return changed;
315285
+ }
315286
+ async preload(families) {
315287
+ if (!Array.isArray(families))
315288
+ throw new Error('[superdoc] fonts.preload expects an array of logical family names, e.g. preload(["Georgia"])');
315289
+ const registry3 = this.#getGate()?.resolveRegistry();
315290
+ if (!registry3)
315291
+ throw new Error("[superdoc] fonts.preload: the font registry is not ready yet");
315292
+ const requests = families.map((logical) => ({
315293
+ family: this.#resolver.resolvePrimaryPhysicalFamily(logical),
315294
+ weight: "400",
315295
+ style: "normal"
315296
+ }));
315297
+ await registry3.awaitFaceRequests(requests);
315298
+ }
315299
+ #reflowIfChanged(signatureBefore) {
315300
+ if (this.#resolver.signature !== signatureBefore)
315301
+ this.#queueRuntimeReflow();
315302
+ }
315303
+ #applyMappings(mappings) {
315304
+ if (!mappings)
315305
+ return false;
315306
+ const before = this.#resolver.signature;
315307
+ for (const [logicalFamily, physicalFamily] of Object.entries(mappings))
315308
+ this.#resolver.map(logicalFamily, physicalFamily);
315309
+ return this.#resolver.signature !== before;
315310
+ }
315311
+ #queueRuntimeReflow() {
315312
+ if (this.#runtimeReflowQueued)
315313
+ return;
315314
+ this.#runtimeReflowQueued = true;
315315
+ const token$1 = ++this.#runtimeReflowToken;
315316
+ this.#scheduleMicrotask(() => {
315317
+ if (!this.#runtimeReflowQueued || token$1 !== this.#runtimeReflowToken)
315318
+ return;
315319
+ this.#runtimeReflowQueued = false;
315320
+ const availabilityChanged = this.#runtimeAvailabilityChanged;
315321
+ this.#runtimeAvailabilityChanged = false;
315322
+ this.#onDocumentFontConfigApplied();
315323
+ this.#getGate()?.notifyDocumentFontConfigChanged({ availabilityChanged });
315324
+ });
315325
+ }
315326
+ #cancelPendingRuntimeReflow() {
315327
+ this.#runtimeAvailabilityChanged = false;
315328
+ if (!this.#runtimeReflowQueued)
315329
+ return;
315330
+ this.#runtimeReflowQueued = false;
315331
+ this.#runtimeReflowToken += 1;
315332
+ }
315333
+ }, DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE, NATIVE_SELECTION_STYLES = `
314956
315334
  /* Hide native browser selection on layout engine content.
314957
315335
  * We render our own selection overlay via PresentationEditor's #localSelectionLayer
314958
315336
  * for precise control over selection geometry across pages and zoom levels. */
@@ -315029,7 +315407,7 @@ menclose::after {
315029
315407
  return;
315030
315408
  console.log(...args$1);
315031
315409
  }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, SEMANTIC_RESIZE_DEBOUNCE_MS = 120, MIN_SEMANTIC_CONTENT_WIDTH_PX = 1, GLOBAL_PERFORMANCE, PresentationEditor, ICONS, TEXTS, tableActionsOptions, TRACKED_MARK_NAMES;
315032
- var init_src_CF4og_LY_es = __esm(() => {
315410
+ var init_src_DvgAvHbj_es = __esm(() => {
315033
315411
  init_rolldown_runtime_Bg48TavK_es();
315034
315412
  init_SuperConverter_B9mZiCO9_es();
315035
315413
  init_jszip_C49i9kUs_es();
@@ -341904,6 +342282,33 @@ function print() { __p += __j.call(arguments, '') }
341904
342282
  "wave",
341905
342283
  "doubleWave"
341906
342284
  ]);
342285
+ SETTLED_STATUSES = [
342286
+ "loaded",
342287
+ "failed",
342288
+ "timed_out",
342289
+ "fallback_used"
342290
+ ];
342291
+ BUNDLED_SUBSTITUTES = Object.freeze({
342292
+ calibri: "Carlito",
342293
+ cambria: "Caladea",
342294
+ arial: "Liberation Sans",
342295
+ "times new roman": "Liberation Serif",
342296
+ "courier new": "Liberation Mono"
342297
+ });
342298
+ defaultResolver = new FontResolver;
342299
+ DEFAULT_FONT_MEASURE_CONTEXT = Object.freeze({
342300
+ resolvePhysical: (cssFontFamily, _face) => resolvePhysicalFamily(cssFontFamily),
342301
+ fontSignature: ""
342302
+ });
342303
+ BUNDLED_MANIFEST = Object.freeze([
342304
+ family("Carlito", "Carlito", "OFL-1.1"),
342305
+ family("Caladea", "Caladea", "Apache-2.0"),
342306
+ family("Liberation Sans", "LiberationSans", "OFL-1.1"),
342307
+ family("Liberation Serif", "LiberationSerif", "OFL-1.1"),
342308
+ family("Liberation Mono", "LiberationMono", "OFL-1.1")
342309
+ ]);
342310
+ installedRegistries = /* @__PURE__ */ new WeakMap;
342311
+ registriesByFontSet = /* @__PURE__ */ new WeakMap;
341907
342312
  PX_PER_PT$12 = 96 / 72;
341908
342313
  BORDER_SIDES2 = [
341909
342314
  "top",
@@ -341935,29 +342340,6 @@ function print() { __p += __j.call(arguments, '') }
341935
342340
  "sdtDocpartId",
341936
342341
  "sdtDocpartInstruction"
341937
342342
  ];
341938
- SETTLED_STATUSES = [
341939
- "loaded",
341940
- "failed",
341941
- "timed_out",
341942
- "fallback_used"
341943
- ];
341944
- BUNDLED_SUBSTITUTES = Object.freeze({
341945
- calibri: "Carlito",
341946
- cambria: "Caladea",
341947
- arial: "Liberation Sans",
341948
- "times new roman": "Liberation Serif",
341949
- "courier new": "Liberation Mono"
341950
- });
341951
- defaultResolver = new FontResolver;
341952
- BUNDLED_MANIFEST = Object.freeze([
341953
- family("Carlito", "Carlito", "OFL-1.1"),
341954
- family("Caladea", "Caladea", "Apache-2.0"),
341955
- family("Liberation Sans", "LiberationSans", "OFL-1.1"),
341956
- family("Liberation Serif", "LiberationSerif", "OFL-1.1"),
341957
- family("Liberation Mono", "LiberationMono", "OFL-1.1")
341958
- ]);
341959
- installedRegistries = /* @__PURE__ */ new WeakMap;
341960
- registriesByFontSet = /* @__PURE__ */ new WeakMap;
341961
342343
  OPERATOR_CHARS = new Set([
341962
342344
  "+",
341963
342345
  "-",
@@ -343190,8 +343572,19 @@ function print() { __p += __j.call(arguments, '') }
343190
343572
  #selectionSync = new SelectionSyncCoordinator;
343191
343573
  #fontGate = null;
343192
343574
  #fontResolver = createFontResolver();
343575
+ #nextFontsChangedSource = null;
343576
+ #fontController = new DocumentFontController({
343577
+ resolver: this.#fontResolver,
343578
+ getGate: () => this.#fontGate,
343579
+ onDocumentFontConfigApplied: () => {
343580
+ this.#nextFontsChangedSource = "config-change";
343581
+ }
343582
+ });
343193
343583
  #fontPlanBlocks = null;
343584
+ #fontPlan = null;
343585
+ #hasFace = (family$1, weight, style2) => this.#fontGate ? this.#fontGate.resolveRegistry().hasFace(family$1, weight, style2) : false;
343194
343586
  #lastFontsChangedKey = null;
343587
+ #lastFontsChangedVersion = -1;
343195
343588
  #lastFontsChangedPayload = null;
343196
343589
  #shouldScrollSelectionIntoView = false;
343197
343590
  #suppressSelectionScrollUntilRaf = false;
@@ -343422,7 +343815,7 @@ function print() { __p += __j.call(arguments, '') }
343422
343815
  initBudgetMs: HEADER_FOOTER_INIT_BUDGET_MS,
343423
343816
  defaultPageSize: DEFAULT_PAGE_SIZE,
343424
343817
  defaultMargins: DEFAULT_MARGINS,
343425
- getFontSignature: () => this.#fontResolver.signature
343818
+ getFontSignature: () => this.#layoutFontSignature
343426
343819
  });
343427
343820
  this.#headerFooterSession.setHoverElements({
343428
343821
  hoverOverlay: this.#hoverOverlay,
@@ -343476,17 +343869,9 @@ function print() { __p += __j.call(arguments, '') }
343476
343869
  getDocumentFonts: () => {
343477
343870
  return this.#editor.converter?.getDocumentFonts?.() ?? [];
343478
343871
  },
343479
- requestReflow: () => {
343480
- this.#layoutState = {
343481
- ...this.#layoutState,
343482
- blocks: [],
343483
- measures: [],
343484
- layout: null
343485
- };
343486
- this.#pendingDocChange = true;
343487
- this.#scheduleRerender();
343488
- },
343489
- getRequiredFaces: () => planRequiredFontFaces(this.#fontPlanBlocks, this.#fontResolver),
343872
+ requestReflow: () => this.#requestFontReflow(),
343873
+ getRequiredFaces: () => this.#fontPlan?.requiredFaces ?? [],
343874
+ getUsedFaces: () => this.#fontPlan?.usedFaces ?? [],
343490
343875
  fontResolver: this.#fontResolver,
343491
343876
  onRegistryResolved: (registry3) => installBundledSubstitutes(registry3, {
343492
343877
  assetBaseUrl: this.#options.fontAssets?.assetBaseUrl,
@@ -343503,6 +343888,7 @@ function print() { __p += __j.call(arguments, '') }
343503
343888
  } : null;
343504
343889
  }
343505
343890
  });
343891
+ this.#fontController.applyInitialConfig(this.#options.fontAssets);
343506
343892
  if (typeof this.#options.disableContextMenu === "boolean")
343507
343893
  this.setContextMenuDisabled(this.#options.disableContextMenu);
343508
343894
  this.#setupHeaderFooterSession();
@@ -344460,18 +344846,46 @@ function print() { __p += __j.call(arguments, '') }
344460
344846
  return this.#fontGate?.getReport() ?? [];
344461
344847
  }
344462
344848
  getMissingFonts() {
344463
- return this.getFontReport().filter((record3) => record3.missing).map((record3) => record3.logicalFamily);
344849
+ return [...new Set(this.getFontReport().filter((record3) => record3.missing).map((record3) => record3.logicalFamily))];
344850
+ }
344851
+ mapFonts(mappings) {
344852
+ this.#fontController.map(mappings);
344853
+ }
344854
+ unmapFonts(families) {
344855
+ this.#fontController.unmap(families);
344856
+ }
344857
+ addFonts(families) {
344858
+ this.#fontController.add(families);
344859
+ }
344860
+ async preloadFonts(families) {
344861
+ await this.#fontController.preload(families);
344862
+ }
344863
+ #requestFontReflow() {
344864
+ this.#layoutState = {
344865
+ ...this.#layoutState,
344866
+ blocks: [],
344867
+ measures: [],
344868
+ layout: null
344869
+ };
344870
+ this.#pendingDocChange = true;
344871
+ this.#scheduleRerender();
344464
344872
  }
344465
344873
  #emitFontsChangedIfChanged(summary) {
344466
344874
  const gate = this.#fontGate;
344467
344875
  if (!gate)
344468
344876
  return;
344469
344877
  const version$1 = gate.fontConfigVersion;
344470
- const key2 = `${version$1}|${summary ? summary.results.map((result) => `${result.family}:${result.status}`).sort().join(",") : ""}`;
344878
+ const statusKey = summary ? summary.results.map((result) => `${result.family}:${result.status}`).sort().join(",") : "";
344879
+ const key2 = `${version$1}|${this.#fontPlan?.effectiveSignature ?? ""}|${statusKey}`;
344471
344880
  if (key2 === this.#lastFontsChangedKey)
344472
344881
  return;
344473
344882
  const isInitial = this.#lastFontsChangedKey === null;
344883
+ const epochBumped = !isInitial && version$1 !== this.#lastFontsChangedVersion;
344474
344884
  this.#lastFontsChangedKey = key2;
344885
+ this.#lastFontsChangedVersion = version$1;
344886
+ const pendingSource = this.#nextFontsChangedSource;
344887
+ this.#nextFontsChangedSource = null;
344888
+ const source = isInitial ? "initial" : pendingSource ?? (epochBumped ? "late-load" : "render-change");
344475
344889
  let resolutions;
344476
344890
  try {
344477
344891
  resolutions = gate.getReport();
@@ -344479,9 +344893,9 @@ function print() { __p += __j.call(arguments, '') }
344479
344893
  return;
344480
344894
  }
344481
344895
  const payload = {
344482
- documentFonts: resolutions.map((record3) => record3.logicalFamily),
344896
+ documentFonts: [...new Set(resolutions.map((record3) => record3.logicalFamily))],
344483
344897
  resolutions,
344484
- missingFonts: resolutions.filter((record3) => record3.missing).map((record3) => record3.logicalFamily),
344898
+ missingFonts: [...new Set(resolutions.filter((record3) => record3.missing).map((record3) => record3.logicalFamily))],
344485
344899
  loadSummary: summary ?? {
344486
344900
  loaded: 0,
344487
344901
  failed: 0,
@@ -344489,7 +344903,7 @@ function print() { __p += __j.call(arguments, '') }
344489
344903
  fallbackUsed: 0,
344490
344904
  results: []
344491
344905
  },
344492
- source: isInitial ? "initial" : "late-load",
344906
+ source,
344493
344907
  version: version$1
344494
344908
  };
344495
344909
  this.#lastFontsChangedPayload = payload;
@@ -344500,6 +344914,14 @@ function print() { __p += __j.call(arguments, '') }
344500
344914
  getLastFontsChangedPayload() {
344501
344915
  return this.#lastFontsChangedPayload;
344502
344916
  }
344917
+ #resetFontReportStateForDocumentChange() {
344918
+ this.#nextFontsChangedSource = null;
344919
+ this.#lastFontsChangedKey = null;
344920
+ this.#lastFontsChangedVersion = -1;
344921
+ this.#lastFontsChangedPayload = null;
344922
+ this.#fontPlan = null;
344923
+ this.#fontPlanBlocks = null;
344924
+ }
344503
344925
  getLayoutOptions() {
344504
344926
  return { ...this.#layoutOptions };
344505
344927
  }
@@ -344648,7 +345070,7 @@ function print() { __p += __j.call(arguments, '') }
344648
345070
  flowMode: this.#layoutOptions.flowMode ?? "paginated",
344649
345071
  blocks: blocks2,
344650
345072
  measures,
344651
- fontSignature: this.#fontResolver.signature
345073
+ fontSignature: this.#layoutFontSignature
344652
345074
  });
344653
345075
  const isSemanticFlow = this.#layoutOptions.flowMode === "semantic";
344654
345076
  this.#ensurePainter();
@@ -345368,6 +345790,7 @@ function print() { __p += __j.call(arguments, '') }
345368
345790
  this.#postPaintPipeline.destroy();
345369
345791
  this.#proofingManager?.dispose();
345370
345792
  this.#proofingManager = null;
345793
+ this.#fontController.dispose();
345371
345794
  this.#fontGate?.dispose();
345372
345795
  this.#fontGate = null;
345373
345796
  if (this.#cursorUpdateTimer !== null) {
@@ -345728,7 +346151,10 @@ function print() { __p += __j.call(arguments, '') }
345728
346151
  });
345729
346152
  const handleDocumentReplaced = () => {
345730
346153
  this.#fontGate?.resetForDocumentChange();
345731
- this.#fontResolver.reset();
346154
+ this.#fontController.reset();
346155
+ this.#layoutFontSignature = "";
346156
+ this.#fontController.applyInitialConfig(this.#options.fontAssets);
346157
+ this.#resetFontReportStateForDocumentChange();
345732
346158
  this.#refreshHeaderFooterStructureThenRerender({ purgeCachedEditors: true });
345733
346159
  };
345734
346160
  this.#editor.on("documentReplaced", handleDocumentReplaced);
@@ -346853,9 +347279,13 @@ function print() { __p += __j.call(arguments, '') }
346853
347279
  const previousBlocks = this.#layoutState.blocks;
346854
347280
  const previousLayout = this.#layoutState.layout;
346855
347281
  const previousMeasures = this.#layoutState.measures;
346856
- const resolvePhysical = (css) => this.#fontResolver.resolvePhysicalFamily(css);
346857
- const fontSignature = this.#fontResolver.signature;
347282
+ const resolvePhysical = (css, face) => this.#fontResolver.resolvePhysicalFamilyForFace(css, face, this.#hasFace);
347283
+ let fontSignature = "";
346858
347284
  const previousFontSignature = this.#layoutFontSignature;
347285
+ let fontMeasureContext = {
347286
+ resolvePhysical,
347287
+ fontSignature
347288
+ };
346859
347289
  let layout;
346860
347290
  let measures;
346861
347291
  let resolvedLayout;
@@ -346874,13 +347304,19 @@ function print() { __p += __j.call(arguments, '') }
346874
347304
  ...headerFooterInput ? this.#collectHeaderFooterFaceBlocks(headerFooterInput) : [],
346875
347305
  ...!isSemanticFlow && footnotesLayoutInput?.blocksById ? [...footnotesLayoutInput.blocksById.values()].flat() : []
346876
347306
  ];
347307
+ this.#fontPlan = planFontFaces(this.#fontPlanBlocks, this.#fontResolver, this.#hasFace);
347308
+ fontSignature = this.#fontPlan.effectiveSignature;
347309
+ fontMeasureContext = {
347310
+ resolvePhysical,
347311
+ fontSignature
347312
+ };
346877
347313
  const fontSummary = await this.#fontGate?.ensureReadyForMeasure() ?? null;
346878
347314
  this.#emitFontsChangedIfChanged(fontSummary);
346879
347315
  } catch {}
346880
347316
  try {
346881
347317
  const incrementalLayoutStart = perfNow();
346882
- const result = await incrementalLayout(previousBlocks, previousLayout, blocksForLayout, layoutOptions, (block, constraints) => measureBlock(block, constraints, resolvePhysical), headerFooterInput ?? undefined, previousMeasures, {
346883
- fontSignature,
347318
+ const result = await incrementalLayout(previousBlocks, previousLayout, blocksForLayout, layoutOptions, (block, constraints) => measureBlock(block, constraints, fontMeasureContext), headerFooterInput ?? undefined, previousMeasures, {
347319
+ fontContext: fontMeasureContext,
346884
347320
  previousFontSignature
346885
347321
  });
346886
347322
  perfLog(`[Perf] incrementalLayout: ${(perfNow() - incrementalLayoutStart).toFixed(2)}ms`);
@@ -347033,7 +347469,7 @@ function print() { __p += __j.call(arguments, '') }
347033
347469
  pageGap: this.#layoutState.layout?.pageGap ?? effectiveGap,
347034
347470
  showFormattingMarks: this.#layoutOptions.showFormattingMarks ?? false,
347035
347471
  contentControlsChrome: this.#layoutOptions.contentControlsChrome ?? "default",
347036
- resolvePhysical: (css) => this.#fontResolver.resolvePhysicalFamily(css)
347472
+ resolvePhysical: (css, face) => this.#fontResolver.resolvePhysicalFamilyForFace(css, face, this.#hasFace)
347037
347473
  });
347038
347474
  const currentZoom = this.#layoutOptions.zoom ?? 1;
347039
347475
  if (currentZoom !== 1)
@@ -347785,7 +348221,7 @@ function print() { __p += __j.call(arguments, '') }
347785
348221
  }
347786
348222
  async#layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata) {
347787
348223
  if (this.#headerFooterSession)
347788
- await this.#headerFooterSession.layoutPerRId(headerFooterInput, layout, sectionMetadata, this.#fontResolver);
348224
+ await this.#headerFooterSession.layoutPerRId(headerFooterInput, layout, sectionMetadata, this.#fontResolver, this.#hasFace, this.#fontPlan?.effectiveSignature ?? "");
347789
348225
  }
347790
348226
  #updateDecorationProviders(resolvedLayout) {
347791
348227
  this.#headerFooterSession?.updateDecorationProviders(resolvedLayout);
@@ -349732,7 +350168,7 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
349732
350168
 
349733
350169
  // ../../packages/superdoc/dist/super-editor.es.js
349734
350170
  var init_super_editor_es = __esm(() => {
349735
- init_src_CF4og_LY_es();
350171
+ init_src_DvgAvHbj_es();
349736
350172
  init_SuperConverter_B9mZiCO9_es();
349737
350173
  init_jszip_C49i9kUs_es();
349738
350174
  init_xml_js_CqGKpaft_es();