@superdoc-dev/cli 0.16.0-next.21 → 0.16.0-next.23

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 +7 -7
package/dist/index.js CHANGED
@@ -230111,7 +230111,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
230111
230111
  init_remark_gfm_BhnWr3yf_es();
230112
230112
  });
230113
230113
 
230114
- // ../../packages/superdoc/dist/chunks/src-CF4og_LY.es.js
230114
+ // ../../packages/superdoc/dist/chunks/src-DvgAvHbj.es.js
230115
230115
  function deleteProps(obj, propOrProps) {
230116
230116
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
230117
230117
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -270389,6 +270389,221 @@ function computeTabWidth(currentPos, justification, tabs, hangingIndent, firstLi
270389
270389
  tabWidth = nextDefaultTabStop - currentPos;
270390
270390
  return tabWidth;
270391
270391
  }
270392
+ function isSettled(status) {
270393
+ return SETTLED_STATUSES.includes(status);
270394
+ }
270395
+ function normalizeFamilyKey$2(family$1) {
270396
+ return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
270397
+ }
270398
+ function splitStack(cssFontFamily) {
270399
+ return cssFontFamily.split(",").map((part) => part.trim()).filter(Boolean);
270400
+ }
270401
+ function createFontResolver() {
270402
+ return new FontResolver;
270403
+ }
270404
+ function resolveFontFamily2(logicalFamily) {
270405
+ return defaultResolver.resolveFontFamily(logicalFamily);
270406
+ }
270407
+ function resolvePhysicalFamily(cssFontFamily) {
270408
+ return defaultResolver.resolvePhysicalFamily(cssFontFamily);
270409
+ }
270410
+ function resolveFace(logicalFamily, face, hasFace) {
270411
+ return defaultResolver.resolveFace(logicalFamily, face, hasFace);
270412
+ }
270413
+ function getFontConfigVersion() {
270414
+ return fontConfigVersion;
270415
+ }
270416
+ function bumpFontConfigVersion() {
270417
+ return fontConfigVersion += 1;
270418
+ }
270419
+ function fourFaces(filePrefix) {
270420
+ return [
270421
+ {
270422
+ weight: "normal",
270423
+ style: "normal",
270424
+ file: `${filePrefix}-Regular.woff2`
270425
+ },
270426
+ {
270427
+ weight: "bold",
270428
+ style: "normal",
270429
+ file: `${filePrefix}-Bold.woff2`
270430
+ },
270431
+ {
270432
+ weight: "normal",
270433
+ style: "italic",
270434
+ file: `${filePrefix}-Italic.woff2`
270435
+ },
270436
+ {
270437
+ weight: "bold",
270438
+ style: "italic",
270439
+ file: `${filePrefix}-BoldItalic.woff2`
270440
+ }
270441
+ ];
270442
+ }
270443
+ function family(name, filePrefix, license) {
270444
+ return {
270445
+ family: name,
270446
+ license,
270447
+ faces: fourFaces(filePrefix)
270448
+ };
270449
+ }
270450
+ function withTrailingSlash(base5) {
270451
+ return base5.endsWith("/") ? base5 : `${base5}/`;
270452
+ }
270453
+ function joinUrl(base5, file) {
270454
+ return `${withTrailingSlash(base5)}${file}`;
270455
+ }
270456
+ function weightToken(weight) {
270457
+ return weight === "bold" ? "700" : "400";
270458
+ }
270459
+ function bundledAssetSignature(resolve3) {
270460
+ const family$1 = BUNDLED_MANIFEST[0];
270461
+ const face = family$1?.faces[0];
270462
+ if (!family$1 || !face)
270463
+ return "";
270464
+ return resolve3({
270465
+ file: face.file,
270466
+ family: family$1.family,
270467
+ weight: weightToken(face.weight),
270468
+ style: face.style,
270469
+ source: "bundled-substitute"
270470
+ });
270471
+ }
270472
+ function installBundledSubstitutes(registry2, options = {}) {
270473
+ const resolve3 = options.resolveAssetUrl ?? ((context) => joinUrl(options.assetBaseUrl ?? defaultAssetBase, context.file));
270474
+ const signature = bundledAssetSignature(resolve3);
270475
+ const installed = installedRegistries.get(registry2);
270476
+ if (installed !== undefined) {
270477
+ if (installed !== signature)
270478
+ 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.`);
270479
+ return;
270480
+ }
270481
+ installedRegistries.set(registry2, signature);
270482
+ for (const family$1 of BUNDLED_MANIFEST)
270483
+ for (const face of family$1.faces) {
270484
+ const context = {
270485
+ file: face.file,
270486
+ family: family$1.family,
270487
+ weight: weightToken(face.weight),
270488
+ style: face.style,
270489
+ source: "bundled-substitute"
270490
+ };
270491
+ registry2.register({
270492
+ family: family$1.family,
270493
+ source: `url(${resolve3(context)})`,
270494
+ descriptors: {
270495
+ weight: face.weight,
270496
+ style: face.style
270497
+ }
270498
+ });
270499
+ }
270500
+ }
270501
+ function buildFontReport(logicalFamilies, registry2, resolver2) {
270502
+ const seen = /* @__PURE__ */ new Set;
270503
+ const report = [];
270504
+ for (const logical of logicalFamilies) {
270505
+ if (!logical || seen.has(logical))
270506
+ continue;
270507
+ seen.add(logical);
270508
+ const { physicalFamily, reason } = resolver2 ? resolver2.resolveFontFamily(logical) : resolveFontFamily2(logical);
270509
+ const loadStatus = registry2.getStatus(physicalFamily);
270510
+ report.push({
270511
+ logicalFamily: logical,
270512
+ physicalFamily,
270513
+ reason,
270514
+ loadStatus,
270515
+ exportFamily: logical,
270516
+ missing: isSettled(loadStatus) && loadStatus !== "loaded"
270517
+ });
270518
+ }
270519
+ return report;
270520
+ }
270521
+ function buildFaceReport(usedFaces, registry2, resolver2) {
270522
+ const hasFace = (family$1, weight, style2) => registry2.hasFace(family$1, weight, style2);
270523
+ const seen = /* @__PURE__ */ new Set;
270524
+ const report = [];
270525
+ for (const { logicalFamily, weight, style: style2 } of usedFaces) {
270526
+ if (!logicalFamily)
270527
+ continue;
270528
+ const key2 = `${logicalFamily.toLowerCase()}|${weight}|${style2}`;
270529
+ if (seen.has(key2))
270530
+ continue;
270531
+ seen.add(key2);
270532
+ const face = {
270533
+ weight,
270534
+ style: style2
270535
+ };
270536
+ const { physicalFamily, reason } = resolver2 ? resolver2.resolveFace(logicalFamily, face, hasFace) : resolveFace(logicalFamily, face, hasFace);
270537
+ const loadStatus = registry2.getFaceStatus({
270538
+ family: physicalFamily,
270539
+ weight,
270540
+ style: style2
270541
+ });
270542
+ const missing = reason === "fallback_face_absent" || isSettled(loadStatus) && loadStatus !== "loaded";
270543
+ report.push({
270544
+ logicalFamily,
270545
+ physicalFamily,
270546
+ reason,
270547
+ loadStatus,
270548
+ exportFamily: logicalFamily,
270549
+ missing,
270550
+ face
270551
+ });
270552
+ }
270553
+ return report;
270554
+ }
270555
+ function quoteFamily(family$1) {
270556
+ return `"${family$1.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
270557
+ }
270558
+ function canonicalizeFontSource(source) {
270559
+ const match$1 = /^\s*url\(\s*([\s\S]*?)\s*\)\s*$/i.exec(source);
270560
+ if (!match$1)
270561
+ return source;
270562
+ let inner = match$1[1].trim();
270563
+ if (inner.startsWith('"') && inner.endsWith('"') || inner.startsWith("'") && inner.endsWith("'"))
270564
+ inner = inner.slice(1, -1);
270565
+ return `url(${JSON.stringify(inner)})`;
270566
+ }
270567
+ function normalizeFamilyKey$1(family$1) {
270568
+ return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
270569
+ }
270570
+ function normalizeWeight(weight) {
270571
+ if (weight === undefined)
270572
+ return "400";
270573
+ const w = String(weight).trim().toLowerCase();
270574
+ if (w === "bold" || w === "bolder")
270575
+ return "700";
270576
+ const n = Number(w);
270577
+ return Number.isFinite(n) && n >= 600 ? "700" : "400";
270578
+ }
270579
+ function normalizeStyle$1(style2) {
270580
+ if (!style2)
270581
+ return "normal";
270582
+ const s2 = style2.trim().toLowerCase();
270583
+ return s2.startsWith("italic") || s2.startsWith("oblique") ? "italic" : "normal";
270584
+ }
270585
+ function faceKeyOf$1(family$1, weight, style2) {
270586
+ return `${normalizeFamilyKey$1(family$1)}|${weight}|${style2}`;
270587
+ }
270588
+ function faceProbe(family$1, weight, style2, size$1) {
270589
+ return `${style2 === "italic" ? "italic " : ""}${weight} ${size$1} ${quoteFamily(family$1)}`;
270590
+ }
270591
+ function getFontRegistryFor(fontSet, FontFaceCtor) {
270592
+ if (!fontSet) {
270593
+ if (!domlessRegistry)
270594
+ domlessRegistry = new FontRegistry({});
270595
+ return domlessRegistry;
270596
+ }
270597
+ let registry2 = registriesByFontSet.get(fontSet);
270598
+ if (!registry2) {
270599
+ registry2 = new FontRegistry({
270600
+ fontSet,
270601
+ FontFaceCtor
270602
+ });
270603
+ registriesByFontSet.set(fontSet, registry2);
270604
+ }
270605
+ return registry2;
270606
+ }
270392
270607
  function isResolvedFragmentWithBorders(item) {
270393
270608
  return item !== undefined && item.kind === "fragment" && "paragraphBorders" in item && item.paragraphBorders !== undefined;
270394
270609
  }
@@ -270598,178 +270813,6 @@ function renderPartialEmbeddedTable(params$1) {
270598
270813
  hasSdtContainerChrome: tableResult.hasSdtContainerChrome
270599
270814
  };
270600
270815
  }
270601
- function isSettled(status) {
270602
- return SETTLED_STATUSES.includes(status);
270603
- }
270604
- function normalizeFamilyKey$2(family$1) {
270605
- return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
270606
- }
270607
- function splitStack(cssFontFamily) {
270608
- return cssFontFamily.split(",").map((part) => part.trim()).filter(Boolean);
270609
- }
270610
- function createFontResolver() {
270611
- return new FontResolver;
270612
- }
270613
- function resolveFontFamily2(logicalFamily) {
270614
- return defaultResolver.resolveFontFamily(logicalFamily);
270615
- }
270616
- function resolvePhysicalFamily(cssFontFamily) {
270617
- return defaultResolver.resolvePhysicalFamily(cssFontFamily);
270618
- }
270619
- function resolvePrimaryPhysicalFamily(family$1) {
270620
- return defaultResolver.resolvePrimaryPhysicalFamily(family$1);
270621
- }
270622
- function getFontConfigVersion() {
270623
- return fontConfigVersion;
270624
- }
270625
- function bumpFontConfigVersion() {
270626
- return fontConfigVersion += 1;
270627
- }
270628
- function fourFaces(filePrefix) {
270629
- return [
270630
- {
270631
- weight: "normal",
270632
- style: "normal",
270633
- file: `${filePrefix}-Regular.woff2`
270634
- },
270635
- {
270636
- weight: "bold",
270637
- style: "normal",
270638
- file: `${filePrefix}-Bold.woff2`
270639
- },
270640
- {
270641
- weight: "normal",
270642
- style: "italic",
270643
- file: `${filePrefix}-Italic.woff2`
270644
- },
270645
- {
270646
- weight: "bold",
270647
- style: "italic",
270648
- file: `${filePrefix}-BoldItalic.woff2`
270649
- }
270650
- ];
270651
- }
270652
- function family(name, filePrefix, license) {
270653
- return {
270654
- family: name,
270655
- license,
270656
- faces: fourFaces(filePrefix)
270657
- };
270658
- }
270659
- function withTrailingSlash(base5) {
270660
- return base5.endsWith("/") ? base5 : `${base5}/`;
270661
- }
270662
- function joinUrl(base5, file) {
270663
- return `${withTrailingSlash(base5)}${file}`;
270664
- }
270665
- function weightToken(weight) {
270666
- return weight === "bold" ? "700" : "400";
270667
- }
270668
- function bundledAssetSignature(resolve3) {
270669
- const family$1 = BUNDLED_MANIFEST[0];
270670
- const face = family$1?.faces[0];
270671
- if (!family$1 || !face)
270672
- return "";
270673
- return resolve3({
270674
- file: face.file,
270675
- family: family$1.family,
270676
- weight: weightToken(face.weight),
270677
- style: face.style,
270678
- source: "bundled-substitute"
270679
- });
270680
- }
270681
- function installBundledSubstitutes(registry2, options = {}) {
270682
- const resolve3 = options.resolveAssetUrl ?? ((context) => joinUrl(options.assetBaseUrl ?? defaultAssetBase, context.file));
270683
- const signature = bundledAssetSignature(resolve3);
270684
- const installed = installedRegistries.get(registry2);
270685
- if (installed !== undefined) {
270686
- if (installed !== signature)
270687
- 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.`);
270688
- return;
270689
- }
270690
- installedRegistries.set(registry2, signature);
270691
- for (const family$1 of BUNDLED_MANIFEST)
270692
- for (const face of family$1.faces) {
270693
- const context = {
270694
- file: face.file,
270695
- family: family$1.family,
270696
- weight: weightToken(face.weight),
270697
- style: face.style,
270698
- source: "bundled-substitute"
270699
- };
270700
- registry2.register({
270701
- family: family$1.family,
270702
- source: `url(${resolve3(context)})`,
270703
- descriptors: {
270704
- weight: face.weight,
270705
- style: face.style
270706
- }
270707
- });
270708
- }
270709
- }
270710
- function buildFontReport(logicalFamilies, registry2, resolver2) {
270711
- const seen = /* @__PURE__ */ new Set;
270712
- const report = [];
270713
- for (const logical of logicalFamilies) {
270714
- if (!logical || seen.has(logical))
270715
- continue;
270716
- seen.add(logical);
270717
- const { physicalFamily, reason } = resolver2 ? resolver2.resolveFontFamily(logical) : resolveFontFamily2(logical);
270718
- const loadStatus = registry2.getStatus(physicalFamily);
270719
- report.push({
270720
- logicalFamily: logical,
270721
- physicalFamily,
270722
- reason,
270723
- loadStatus,
270724
- exportFamily: logical,
270725
- missing: isSettled(loadStatus) && loadStatus !== "loaded"
270726
- });
270727
- }
270728
- return report;
270729
- }
270730
- function quoteFamily(family$1) {
270731
- return `"${family$1.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
270732
- }
270733
- function normalizeFamilyKey$1(family$1) {
270734
- return family$1.trim().replace(/^["']|["']$/g, "").toLowerCase();
270735
- }
270736
- function normalizeWeight(weight) {
270737
- if (weight === undefined)
270738
- return "400";
270739
- const w = String(weight).trim().toLowerCase();
270740
- if (w === "bold" || w === "bolder")
270741
- return "700";
270742
- const n = Number(w);
270743
- return Number.isFinite(n) && n >= 600 ? "700" : "400";
270744
- }
270745
- function normalizeStyle$1(style2) {
270746
- if (!style2)
270747
- return "normal";
270748
- const s2 = style2.trim().toLowerCase();
270749
- return s2.startsWith("italic") || s2.startsWith("oblique") ? "italic" : "normal";
270750
- }
270751
- function faceKeyOf$1(family$1, weight, style2) {
270752
- return `${normalizeFamilyKey$1(family$1)}|${weight}|${style2}`;
270753
- }
270754
- function faceProbe(family$1, weight, style2, size$1) {
270755
- return `${style2 === "italic" ? "italic " : ""}${weight} ${size$1} ${quoteFamily(family$1)}`;
270756
- }
270757
- function getFontRegistryFor(fontSet, FontFaceCtor) {
270758
- if (!fontSet) {
270759
- if (!domlessRegistry)
270760
- domlessRegistry = new FontRegistry({});
270761
- return domlessRegistry;
270762
- }
270763
- let registry2 = registriesByFontSet.get(fontSet);
270764
- if (!registry2) {
270765
- registry2 = new FontRegistry({
270766
- fontSet,
270767
- FontFaceCtor
270768
- });
270769
- registriesByFontSet.set(fontSet, registry2);
270770
- }
270771
- return registry2;
270772
- }
270773
270816
  function isDigit(ch) {
270774
270817
  return ch >= "0" && ch <= "9";
270775
270818
  }
@@ -278396,7 +278439,7 @@ function invalidateHeaderFooterCache(cache$2, cacheState, headerBlocks, footerBl
278396
278439
  }
278397
278440
  }
278398
278441
  async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, options, measureBlock$1, headerFooter, previousMeasures, fontRuntime) {
278399
- const fontSignature = fontRuntime?.fontSignature ?? "";
278442
+ const fontSignature = fontRuntime?.fontContext?.fontSignature ?? "";
278400
278443
  const previousFontSignature = fontRuntime?.previousFontSignature ?? "";
278401
278444
  const isSemanticFlow = options.flowMode === "semantic";
278402
278445
  if (isSemanticFlow) {
@@ -278617,7 +278660,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
278617
278660
  measureCache.invalidate(Array.from(tokenResult.affectedBlockIds));
278618
278661
  const remeasureStart = performance.now();
278619
278662
  const currentPerSectionConstraints = computePerSectionConstraints(options, currentBlocks);
278620
- currentMeasures = await remeasureAffectedBlocks(currentBlocks, currentMeasures, tokenResult.affectedBlockIds, currentPerSectionConstraints, measureBlock$1, measureCache);
278663
+ currentMeasures = await remeasureAffectedBlocks(currentBlocks, currentMeasures, tokenResult.affectedBlockIds, currentPerSectionConstraints, measureBlock$1, fontSignature, measureCache);
278621
278664
  const remeasureTime = performance.now() - remeasureStart;
278622
278665
  totalRemeasureTime += remeasureTime;
278623
278666
  perfLog$1(`[Perf] 4.3.${iteration + 1}.1 Re-measure: ${remeasureTime.toFixed(2)}ms`);
@@ -279935,7 +279978,7 @@ function buildNumberingContext(layout, sections, blockById, chapterContextCache)
279935
279978
  }))
279936
279979
  };
279937
279980
  }
279938
- async function remeasureAffectedBlocks(blocks2, measures, affectedBlockIds, perBlockConstraints, measureBlock$1, measureCache$1) {
279981
+ async function remeasureAffectedBlocks(blocks2, measures, affectedBlockIds, perBlockConstraints, measureBlock$1, fontSignature, measureCache$1) {
279939
279982
  const updatedMeasures = [...measures];
279940
279983
  for (let i4 = 0;i4 < blocks2.length; i4++) {
279941
279984
  const block = blocks2[i4];
@@ -279945,7 +279988,7 @@ async function remeasureAffectedBlocks(blocks2, measures, affectedBlockIds, perB
279945
279988
  const newMeasure = await measureBlock$1(block, perBlockConstraints[i4]);
279946
279989
  updatedMeasures[i4] = newMeasure;
279947
279990
  const blockConstraints = perBlockConstraints[i4];
279948
- measureCache$1?.set(block, blockConstraints.maxWidth, blockConstraints.maxHeight, newMeasure);
279991
+ measureCache$1?.set(block, blockConstraints.maxWidth, blockConstraints.maxHeight, newMeasure, fontSignature);
279949
279992
  } catch (error3) {
279950
279993
  console.warn(`[incrementalLayout] Failed to re-measure block ${block.id} after token resolution:`, error3);
279951
279994
  }
@@ -285777,8 +285820,10 @@ function clearTableAutoFitMeasurementCaches() {
285777
285820
  autoFitTableResultCache.clear();
285778
285821
  }
285779
285822
  function buildTableCellContentMetricsCacheKey(cell2, options) {
285823
+ const fontContext = options.fontContext ?? DEFAULT_FONT_MEASURE_CONTEXT;
285780
285824
  return stableSerialize({
285781
285825
  maxWidth: Math.max(1, Math.round(options.maxWidth)),
285826
+ fontSignature: fontContext.fontSignature ?? "",
285782
285827
  layoutEpoch: options.layoutEpoch ?? null,
285783
285828
  attrs: cell2.attrs ?? null,
285784
285829
  paragraph: cell2.paragraph ?? null,
@@ -285792,6 +285837,7 @@ function buildAutoFitTableResultCacheKey(table2, options) {
285792
285837
  columnWidths: table2.columnWidths ?? null,
285793
285838
  rowCount: table2.rows.length,
285794
285839
  maxWidth: Math.max(1, Math.round(options.maxWidth)),
285840
+ fontSignature: options.fontSignature ?? "",
285795
285841
  layoutEpoch: options.layoutEpoch ?? null,
285796
285842
  cellMetricKeys: options.cellMetricKeys,
285797
285843
  workingGrid: {
@@ -285831,7 +285877,12 @@ function setCachedAutoFitTableResult(cacheKey, result) {
285831
285877
  autoFitTableResultCache.set(cacheKey, result);
285832
285878
  }
285833
285879
  async function measureTableCellContentMetrics(cell2, options) {
285834
- const cacheKey = buildTableCellContentMetricsCacheKey(cell2, options);
285880
+ const fontContext = options.fontContext ?? DEFAULT_FONT_MEASURE_CONTEXT;
285881
+ const normalizedOptions = {
285882
+ ...options,
285883
+ fontContext
285884
+ };
285885
+ const cacheKey = buildTableCellContentMetricsCacheKey(cell2, normalizedOptions);
285835
285886
  const cached = tableCellMetricsCache.get(cacheKey);
285836
285887
  if (cached)
285837
285888
  return cached;
@@ -285848,7 +285899,7 @@ async function measureTableCellContentMetrics(cell2, options) {
285848
285899
  let minContentWidthPx = 0;
285849
285900
  let maxContentWidthPx = 0;
285850
285901
  for (const block of contentBlocks) {
285851
- const metrics = await measureIntrinsicBlockWidthMetrics(block, options);
285902
+ const metrics = await measureIntrinsicBlockWidthMetrics(block, normalizedOptions);
285852
285903
  minContentWidthPx = Math.max(minContentWidthPx, metrics.minWidthPx);
285853
285904
  maxContentWidthPx = Math.max(maxContentWidthPx, metrics.maxWidthPx);
285854
285905
  }
@@ -285859,7 +285910,7 @@ async function measureTableCellContentMetrics(cell2, options) {
285859
285910
  tableCellMetricsCache.set(cacheKey, result);
285860
285911
  return result;
285861
285912
  }
285862
- async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayout, measureBlock$1) {
285913
+ async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayout, measureBlock$1, fontContext = DEFAULT_FONT_MEASURE_CONTEXT) {
285863
285914
  const tableMeasurementBasis = Math.max(1, fixedLayout.totalWidth);
285864
285915
  const cellMetricKeys = [];
285865
285916
  const rowMetrics = await Promise.all(table2.rows.map(async (row2, rowIndex) => {
@@ -285870,10 +285921,14 @@ async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayo
285870
285921
  const normalizedCell = normalizedRow.cells?.[cellIndex];
285871
285922
  const span = normalizedCell?.span ?? cell2.colSpan ?? 1;
285872
285923
  const measurementMaxWidth = resolveAutoFitCellMeasurementMaxWidth(cell2, normalizedCell, span, fixedLayout, tableMeasurementBasis, workingInput.gridColumnCount);
285873
- cellMetricKeys.push(buildTableCellContentMetricsCacheKey(cell2, { maxWidth: measurementMaxWidth }));
285924
+ cellMetricKeys.push(buildTableCellContentMetricsCacheKey(cell2, {
285925
+ maxWidth: measurementMaxWidth,
285926
+ fontContext
285927
+ }));
285874
285928
  const metrics = await measureTableCellContentMetrics(cell2, {
285875
285929
  maxWidth: measurementMaxWidth,
285876
- measureBlock: measureBlock$1
285930
+ measureBlock: measureBlock$1,
285931
+ fontContext
285877
285932
  });
285878
285933
  return {
285879
285934
  cellIndex,
@@ -285905,7 +285960,7 @@ async function measureTableAutoFitContentMetrics(table2, workingInput, fixedLayo
285905
285960
  }
285906
285961
  async function measureIntrinsicBlockWidthMetrics(block, options) {
285907
285962
  if (block.kind === "paragraph")
285908
- return measureParagraphIntrinsicWidthMetrics(block, options.measureBlock);
285963
+ return measureParagraphIntrinsicWidthMetrics(block, options.measureBlock, options.fontContext);
285909
285964
  if (block.kind === "table")
285910
285965
  return measureNestedTableIntrinsicWidthMetrics(block, options);
285911
285966
  const intrinsicWidth = getIntrinsicAtomicBlockWidth(block);
@@ -285914,13 +285969,13 @@ async function measureIntrinsicBlockWidthMetrics(block, options) {
285914
285969
  maxWidthPx: intrinsicWidth
285915
285970
  };
285916
285971
  }
285917
- async function measureParagraphIntrinsicWidthMetrics(paragraph2, measureBlock$1) {
285972
+ async function measureParagraphIntrinsicWidthMetrics(paragraph2, measureBlock$1, fontContext) {
285918
285973
  const maxLineWidth = (await measureBlock$1(paragraph2, {
285919
285974
  maxWidth: NO_WRAP_MAX_WIDTH,
285920
285975
  maxHeight: Infinity
285921
285976
  })).lines.reduce((widest, line) => Math.max(widest, line.width), 0);
285922
285977
  return {
285923
- minWidthPx: measureParagraphMinTokenWidth(paragraph2),
285978
+ minWidthPx: measureParagraphMinTokenWidth(paragraph2, fontContext),
285924
285979
  maxWidthPx: maxLineWidth
285925
285980
  };
285926
285981
  }
@@ -285939,7 +285994,7 @@ async function measureNestedTableIntrinsicWidthMetrics(table2, options) {
285939
285994
  maxWidthPx: nestedMeasure.totalWidth
285940
285995
  };
285941
285996
  }
285942
- function measureParagraphMinTokenWidth(paragraph2) {
285997
+ function measureParagraphMinTokenWidth(paragraph2, fontContext) {
285943
285998
  let widestToken = 0;
285944
285999
  let currentTokenWidth = 0;
285945
286000
  const flushToken = () => {
@@ -285954,7 +286009,7 @@ function measureParagraphMinTokenWidth(paragraph2) {
285954
286009
  if (isTextLikeRun(run2)) {
285955
286010
  accumulateTextRunMinTokenWidth(run2, (width) => {
285956
286011
  currentTokenWidth += width;
285957
- }, flushToken);
286012
+ }, flushToken, fontContext);
285958
286013
  continue;
285959
286014
  }
285960
286015
  flushToken();
@@ -285963,7 +286018,7 @@ function measureParagraphMinTokenWidth(paragraph2) {
285963
286018
  continue;
285964
286019
  }
285965
286020
  if (run2.kind === "fieldAnnotation") {
285966
- widestToken = Math.max(widestToken, measureFieldAnnotationWidth(run2));
286021
+ widestToken = Math.max(widestToken, measureFieldAnnotationWidth(run2, fontContext));
285967
286022
  continue;
285968
286023
  }
285969
286024
  if (run2.kind === "math")
@@ -285972,8 +286027,8 @@ function measureParagraphMinTokenWidth(paragraph2) {
285972
286027
  flushToken();
285973
286028
  return widestToken;
285974
286029
  }
285975
- function accumulateTextRunMinTokenWidth(run2, appendTokenPiece, flushToken) {
285976
- const font = buildFontString$1(run2);
286030
+ function accumulateTextRunMinTokenWidth(run2, appendTokenPiece, flushToken, fontContext) {
286031
+ const font = buildFontString$1(run2, fontContext);
285977
286032
  let cursor = 0;
285978
286033
  for (const boundary of run2.text.matchAll(TOKEN_BOUNDARY_PATTERN)) {
285979
286034
  const boundaryStart = boundary.index ?? cursor;
@@ -286039,14 +286094,19 @@ function getCanvasContext$1() {
286039
286094
  }
286040
286095
  return canvasContext$1;
286041
286096
  }
286042
- function buildFontString$1(run2) {
286097
+ function buildFontString$1(run2, fontContext) {
286043
286098
  const parts = [];
286044
286099
  if (run2.italic)
286045
286100
  parts.push("italic");
286046
286101
  if (run2.bold)
286047
286102
  parts.push("bold");
286048
286103
  parts.push(`${normalizeFontSize$1(run2.fontSize)}px`);
286049
- parts.push(toCssFontFamily(normalizeFontFamily$1(run2.fontFamily)) ?? normalizeFontFamily$1(run2.fontFamily));
286104
+ const face = {
286105
+ weight: run2.bold ? "700" : "400",
286106
+ style: run2.italic ? "italic" : "normal"
286107
+ };
286108
+ const physicalFamily = normalizeFontFamily$1(fontContext.resolvePhysical(normalizeFontFamily$1(run2.fontFamily), face));
286109
+ parts.push(toCssFontFamily(physicalFamily) ?? physicalFamily);
286050
286110
  return parts.join(" ");
286051
286111
  }
286052
286112
  function applyTextTransform$1(text5, run2, startOffset = 0) {
@@ -286071,14 +286131,14 @@ function capitalizeText$1(text5, fullText, startOffset) {
286071
286131
  }
286072
286132
  return result;
286073
286133
  }
286074
- function measureFieldAnnotationWidth(run2) {
286134
+ function measureFieldAnnotationWidth(run2, fontContext) {
286075
286135
  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;
286076
286136
  const font = buildFontString$1({
286077
286137
  fontFamily: normalizeFontFamily$1(run2.fontFamily ?? "Arial"),
286078
286138
  fontSize,
286079
286139
  bold: run2.bold,
286080
286140
  italic: run2.italic
286081
- });
286141
+ }, fontContext);
286082
286142
  return getMeasuredTextWidth(applyTextTransform$1(run2.displayLabel || "", { text: run2.displayLabel || "" }), font, 0, getCanvasContext$1()) + (run2.highlighted === false ? 0 : FIELD_ANNOTATION_PILL_PADDING$1);
286083
286143
  }
286084
286144
  function isExplicitLineBreakRun(run2) {
@@ -286152,14 +286212,20 @@ function getCanvasContext() {
286152
286212
  }
286153
286213
  return canvasContext;
286154
286214
  }
286155
- function buildFontString(run2, resolvePhysical = resolvePhysicalFamily) {
286215
+ function faceOf(run2) {
286216
+ return {
286217
+ weight: run2.bold ? "700" : "400",
286218
+ style: run2.italic ? "italic" : "normal"
286219
+ };
286220
+ }
286221
+ function buildFontString(run2, fontContext) {
286156
286222
  const parts = [];
286157
286223
  if (run2.italic)
286158
286224
  parts.push("italic");
286159
286225
  if (run2.bold)
286160
286226
  parts.push("bold");
286161
286227
  parts.push(`${run2.fontSize}px`);
286162
- const physicalFamily = resolvePhysical(run2.fontFamily);
286228
+ const physicalFamily = fontContext.resolvePhysical(run2.fontFamily, faceOf(run2));
286163
286229
  if (measurementConfig.mode === "deterministic")
286164
286230
  parts.push(measurementConfig.fonts.fallbackStack.length > 0 ? measurementConfig.fonts.fallbackStack.join(", ") : measurementConfig.fonts.deterministicFamily);
286165
286231
  else
@@ -286224,17 +286290,17 @@ function calculateEmptyParagraphMetrics(fontSize, spacing, fontInfo) {
286224
286290
  function lineHeightFontSize(run2) {
286225
286291
  return resolveBaseFontSizeForVerticalText(run2.fontSize, run2);
286226
286292
  }
286227
- function getFontInfoFromRun(run2) {
286293
+ function getFontInfoFromRun(run2, fontContext) {
286228
286294
  return {
286229
- fontFamily: normalizeFontFamily(run2.fontFamily),
286295
+ fontFamily: normalizeFontFamily(fontContext.resolvePhysical(run2.fontFamily, faceOf(run2))),
286230
286296
  fontSize: normalizeFontSize2(lineHeightFontSize(run2)),
286231
286297
  bold: run2.bold,
286232
286298
  italic: run2.italic
286233
286299
  };
286234
286300
  }
286235
- function updateMaxFontInfo(currentMaxSize, currentMaxInfo, newRun) {
286301
+ function updateMaxFontInfo(currentMaxSize, currentMaxInfo, newRun, fontContext) {
286236
286302
  if (lineHeightFontSize(newRun) >= currentMaxSize)
286237
- return getFontInfoFromRun(newRun);
286303
+ return getFontInfoFromRun(newRun, fontContext);
286238
286304
  return currentMaxInfo;
286239
286305
  }
286240
286306
  function isTextRun$22(run2) {
@@ -286252,7 +286318,7 @@ function isLineBreakRun(run2) {
286252
286318
  function isFieldAnnotationRun(run2) {
286253
286319
  return run2.kind === "fieldAnnotation";
286254
286320
  }
286255
- function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator = ".", resolvePhysical = resolvePhysicalFamily) {
286321
+ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator = ".", fontContext) {
286256
286322
  const result = {
286257
286323
  totalWidth: 0,
286258
286324
  runs: [],
@@ -286273,7 +286339,7 @@ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator
286273
286339
  const textRun = run2;
286274
286340
  const text5 = textRun.text || "";
286275
286341
  if (text5.length > 0) {
286276
- const { font } = buildFontString(textRun, resolvePhysical);
286342
+ const { font } = buildFontString(textRun, fontContext);
286277
286343
  const width = measureRunWidth(text5, font, ctx$1, textRun, 0);
286278
286344
  let beforeDecimalWidth;
286279
286345
  if (!foundDecimal) {
@@ -286327,7 +286393,7 @@ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator
286327
286393
  fontSize,
286328
286394
  bold: run2.bold,
286329
286395
  italic: run2.italic
286330
- }, resolvePhysical);
286396
+ }, fontContext);
286331
286397
  const pillWidth = (run2.displayLabel ? measureRunWidth(run2.displayLabel, font, ctx$1, run2, 0) : 0) + FIELD_ANNOTATION_PILL_PADDING;
286332
286398
  result.runs.push({
286333
286399
  runIndex: i4,
@@ -286343,25 +286409,25 @@ function measureTabAlignmentGroup(startRunIndex, runs2, ctx$1, decimalSeparator
286343
286409
  }
286344
286410
  return result;
286345
286411
  }
286346
- async function measureBlock(block, constraints, resolvePhysical = resolvePhysicalFamily) {
286412
+ async function measureBlock(block, constraints, fontContext = DEFAULT_FONT_MEASURE_CONTEXT) {
286347
286413
  const normalized = normalizeConstraints(constraints);
286348
286414
  if (block.kind === "drawing")
286349
286415
  return measureDrawingBlock(block, normalized);
286350
286416
  if (block.kind === "image")
286351
286417
  return measureImageBlock(block, normalized);
286352
286418
  if (block.kind === "list")
286353
- return measureListBlock(block, normalized, resolvePhysical);
286419
+ return measureListBlock(block, normalized, fontContext);
286354
286420
  if (block.kind === "table")
286355
- return measureTableBlock(block, normalized, resolvePhysical);
286421
+ return measureTableBlock(block, normalized, fontContext);
286356
286422
  if (block.kind === "sectionBreak")
286357
286423
  return { kind: "sectionBreak" };
286358
286424
  if (block.kind === "pageBreak")
286359
286425
  return { kind: "pageBreak" };
286360
286426
  if (block.kind === "columnBreak")
286361
286427
  return { kind: "columnBreak" };
286362
- return measureParagraphBlock(block, normalized.maxWidth, resolvePhysical);
286428
+ return measureParagraphBlock(block, normalized.maxWidth, fontContext);
286363
286429
  }
286364
- async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolvePhysicalFamily) {
286430
+ async function measureParagraphBlock(block, maxWidth, fontContext) {
286365
286431
  const ctx$1 = getCanvasContext();
286366
286432
  const wordLayout = block.attrs?.wordLayout;
286367
286433
  const firstTextRunWithSize = block.runs.find((run2) => isTextRun$22(run2) && ("fontSize" in run2) && run2.fontSize != null);
@@ -286374,7 +286440,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
286374
286440
  fontSize: wordLayout.marker.run.fontSize ?? fallbackFontSize,
286375
286441
  bold: wordLayout.marker.run.bold,
286376
286442
  italic: wordLayout.marker.run.italic
286377
- }, resolvePhysical);
286443
+ }, fontContext);
286378
286444
  const markerText = wordLayout.marker.markerText ?? "";
286379
286445
  const glyphWidth = markerText ? measureText(markerText, markerFont, ctx$1) : 0;
286380
286446
  const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : 8;
@@ -286407,7 +286473,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
286407
286473
  fontSize: marker.run?.fontSize ?? fallbackFontSize,
286408
286474
  bold: marker.run?.bold ?? false,
286409
286475
  italic: marker.run?.italic ?? false
286410
- }, resolvePhysical);
286476
+ }, fontContext);
286411
286477
  return measureText(markerText, markerFont, ctx$1);
286412
286478
  }) ?? textStartPx;
286413
286479
  if (typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft)
@@ -286431,14 +286497,14 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
286431
286497
  if (!dropCapDescriptor.run || !dropCapDescriptor.run.text || !dropCapDescriptor.lines)
286432
286498
  console.warn("Invalid drop cap descriptor - missing required fields:", dropCapDescriptor);
286433
286499
  else {
286434
- const dropCapMeasured = measureDropCap(ctx$1, dropCapDescriptor, spacing, resolvePhysical);
286500
+ const dropCapMeasured = measureDropCap(ctx$1, dropCapDescriptor, spacing, fontContext);
286435
286501
  dropCapMeasure = dropCapMeasured;
286436
286502
  dropCapDescriptor.measuredWidth = dropCapMeasured.width;
286437
286503
  dropCapDescriptor.measuredHeight = dropCapMeasured.height;
286438
286504
  }
286439
286505
  const emptyParagraphRun = normalizedRuns.length === 1 && isEmptyTextRun2(normalizedRuns[0]) && !isEmptySdtPlaceholderRun(normalizedRuns[0]) ? normalizedRuns[0] : null;
286440
286506
  if (emptyParagraphRun) {
286441
- const metrics = calculateEmptyParagraphMetrics(emptyParagraphRun.fontSize ?? DEFAULT_PARAGRAPH_FONT_SIZE, spacing, getFontInfoFromRun(emptyParagraphRun));
286507
+ const metrics = calculateEmptyParagraphMetrics(emptyParagraphRun.fontSize ?? DEFAULT_PARAGRAPH_FONT_SIZE, spacing, getFontInfoFromRun(emptyParagraphRun, fontContext));
286442
286508
  const emptyLine = {
286443
286509
  fromRun: 0,
286444
286510
  fromChar: 0,
@@ -286475,7 +286541,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
286475
286541
  ...markerInfo ? { marker: markerInfo } : {}
286476
286542
  };
286477
286543
  }
286478
- const fallbackFontInfo = firstTextRunWithSize ? getFontInfoFromRun(firstTextRunWithSize) : undefined;
286544
+ const fallbackFontInfo = firstTextRunWithSize ? getFontInfoFromRun(firstTextRunWithSize, fontContext) : undefined;
286479
286545
  let currentLine = null;
286480
286546
  const getEffectiveWidth = (baseWidth) => {
286481
286547
  if (dropCapMeasure && lines.length < dropCapMeasure.lines && dropCapMeasure.mode === "drop")
@@ -286656,7 +286722,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
286656
286722
  if (lineToTrim.fromRun === lineToTrim.toRun && sliceText.trim().length === 0)
286657
286723
  return;
286658
286724
  const keptText = sliceText.slice(0, Math.max(0, sliceText.length - trimCount));
286659
- const { font } = buildFontString(lastRun, resolvePhysical);
286725
+ const { font } = buildFontString(lastRun, fontContext);
286660
286726
  const fullWidth = measureRunWidth(sliceText, font, ctx$1, lastRun, sliceStart);
286661
286727
  const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx$1, lastRun, sliceStart) : 0;
286662
286728
  const delta = Math.max(0, fullWidth - keptWidth);
@@ -286803,7 +286869,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
286803
286869
  toChar: 1,
286804
286870
  width: 0,
286805
286871
  maxFontSize: lastFontSize,
286806
- maxFontInfo: hasSeenTextRun ? undefined : fallbackFontInfo ?? getFontInfoFromRun(run2),
286872
+ maxFontInfo: hasSeenTextRun ? undefined : fallbackFontInfo ?? getFontInfoFromRun(run2, fontContext),
286807
286873
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
286808
286874
  segments: [],
286809
286875
  spaceCount: 0
@@ -286853,7 +286919,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
286853
286919
  if (stop) {
286854
286920
  validateTabStopVal(stop);
286855
286921
  if (stop.val === "end" || stop.val === "center" || stop.val === "decimal") {
286856
- const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx$1, decimalSeparator, resolvePhysical);
286922
+ const groupMeasure = measureTabAlignmentGroup(runIndex + 1, runsToProcess, ctx$1, decimalSeparator, fontContext);
286857
286923
  if (groupMeasure.totalWidth > 0) {
286858
286924
  const relativeTarget = clampedTarget - effectiveIndent;
286859
286925
  let groupStartX;
@@ -287029,7 +287095,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287029
287095
  if (isFieldAnnotationRun(run2)) {
287030
287096
  const displayText = applyTextTransform(run2.displayLabel || "", run2);
287031
287097
  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;
287032
- const annotationFontFamily = run2.fontFamily || "Arial, sans-serif";
287098
+ const annotationFontFamily = fontContext.resolvePhysical(run2.fontFamily || "Arial, sans-serif", faceOf(run2));
287033
287099
  const fontWeight = run2.bold ? "bold" : "normal";
287034
287100
  ctx$1.font = `${run2.italic ? "italic" : "normal"} ${fontWeight} ${annotationFontSize}px ${annotationFontFamily}`;
287035
287101
  const textWidth = displayText ? ctx$1.measureText(displayText).width : 0;
@@ -287130,7 +287196,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287130
287196
  continue;
287131
287197
  }
287132
287198
  if (isEmptySdtPlaceholderRun(run2)) {
287133
- const placeholderFont = buildFontString(run2, resolvePhysical).font;
287199
+ const placeholderFont = buildFontString(run2, fontContext).font;
287134
287200
  const placeholderText = applyTextTransform(EMPTY_SDT_PLACEHOLDER_TEXT, run2);
287135
287201
  const measuredPlaceholderWidth = getMeasuredTextWidth(placeholderText, placeholderFont, run2.letterSpacing ?? 0, ctx$1);
287136
287202
  const fallbackPlaceholderWidth = placeholderText.length * run2.fontSize * 0.45;
@@ -287143,7 +287209,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287143
287209
  toChar: 0,
287144
287210
  width: placeholderWidth,
287145
287211
  maxFontSize: lineHeightFontSize(run2),
287146
- maxFontInfo: getFontInfoFromRun(run2),
287212
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287147
287213
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
287148
287214
  segments: [{
287149
287215
  runIndex,
@@ -287176,7 +287242,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287176
287242
  toChar: 0,
287177
287243
  width: placeholderWidth,
287178
287244
  maxFontSize: lineHeightFontSize(run2),
287179
- maxFontInfo: getFontInfoFromRun(run2),
287245
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287180
287246
  maxWidth: getEffectiveWidth(bodyContentWidth),
287181
287247
  segments: [{
287182
287248
  runIndex,
@@ -287190,7 +287256,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287190
287256
  currentLine.toRun = runIndex;
287191
287257
  currentLine.toChar = 0;
287192
287258
  currentLine.width = roundValue(currentLine.width + boundarySpacing + placeholderWidth);
287193
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
287259
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
287194
287260
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
287195
287261
  appendSegment(currentLine.segments, runIndex, 0, 0, placeholderWidth);
287196
287262
  }
@@ -287202,7 +287268,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287202
287268
  }
287203
287269
  lastFontSize = run2.fontSize;
287204
287270
  hasSeenTextRun = true;
287205
- const { font } = buildFontString(run2, resolvePhysical);
287271
+ const { font } = buildFontString(run2, fontContext);
287206
287272
  const tabSegments = run2.text.split("\t");
287207
287273
  let charPosInRun = 0;
287208
287274
  for (let segmentIndex = 0;segmentIndex < tabSegments.length; segmentIndex++) {
@@ -287222,7 +287288,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287222
287288
  toChar: spacesEndChar,
287223
287289
  width: spacesWidth,
287224
287290
  maxFontSize: lineHeightFontSize(run2),
287225
- maxFontInfo: getFontInfoFromRun(run2),
287291
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287226
287292
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
287227
287293
  segments: [{
287228
287294
  runIndex,
@@ -287254,7 +287320,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287254
287320
  toChar: spacesEndChar,
287255
287321
  width: spacesWidth,
287256
287322
  maxFontSize: lineHeightFontSize(run2),
287257
- maxFontInfo: getFontInfoFromRun(run2),
287323
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287258
287324
  maxWidth: getEffectiveWidth(bodyContentWidth),
287259
287325
  segments: [{
287260
287326
  runIndex,
@@ -287268,7 +287334,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287268
287334
  currentLine.toRun = runIndex;
287269
287335
  currentLine.toChar = spacesEndChar;
287270
287336
  currentLine.width = roundValue(currentLine.width + boundarySpacing + spacesWidth);
287271
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
287337
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
287272
287338
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
287273
287339
  appendSegment(currentLine.segments, runIndex, spacesStartChar, spacesEndChar, spacesWidth);
287274
287340
  currentLine.spaceCount += spacesLength;
@@ -287321,7 +287387,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287321
287387
  toChar: spaceEndChar,
287322
287388
  width: singleSpaceWidth,
287323
287389
  maxFontSize: lineHeightFontSize(run2),
287324
- maxFontInfo: getFontInfoFromRun(run2),
287390
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287325
287391
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
287326
287392
  segments: [{
287327
287393
  runIndex,
@@ -287355,7 +287421,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287355
287421
  toChar: spaceEndChar,
287356
287422
  width: singleSpaceWidth,
287357
287423
  maxFontSize: lineHeightFontSize(run2),
287358
- maxFontInfo: getFontInfoFromRun(run2),
287424
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287359
287425
  maxWidth: getEffectiveWidth(bodyContentWidth),
287360
287426
  segments: [{
287361
287427
  runIndex,
@@ -287369,7 +287435,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287369
287435
  currentLine.toRun = runIndex;
287370
287436
  currentLine.toChar = spaceEndChar;
287371
287437
  currentLine.width = roundValue(currentLine.width + boundarySpacing$1 + singleSpaceWidth);
287372
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
287438
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
287373
287439
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
287374
287440
  let spaceExplicitX;
287375
287441
  let spacePrecedingTabEndX;
@@ -287425,7 +287491,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287425
287491
  currentLine.toChar = chunkEndChar;
287426
287492
  currentLine.width = roundValue(currentLine.width + chunk2.width);
287427
287493
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
287428
- currentLine.maxFontInfo = getFontInfoFromRun(run2);
287494
+ currentLine.maxFontInfo = getFontInfoFromRun(run2, fontContext);
287429
287495
  currentLine.segments.push({
287430
287496
  runIndex,
287431
287497
  fromChar: chunkStartChar,
@@ -287464,7 +287530,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287464
287530
  toChar: chunkEndChar,
287465
287531
  width: chunk2.width,
287466
287532
  maxFontSize: lineHeightFontSize(run2),
287467
- maxFontInfo: getFontInfoFromRun(run2),
287533
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287468
287534
  maxWidth: getEffectiveWidth(contentWidth),
287469
287535
  segments: [{
287470
287536
  runIndex,
@@ -287484,7 +287550,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287484
287550
  charPosInRun = wordEndWithSpace;
287485
287551
  } else {
287486
287552
  const chunkLineMaxWidth = getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
287487
- const metrics = calculateTypographyMetrics(run2.fontSize, spacing, getFontInfoFromRun(run2));
287553
+ const metrics = calculateTypographyMetrics(run2.fontSize, spacing, getFontInfoFromRun(run2, fontContext));
287488
287554
  const chunkLine = {
287489
287555
  fromRun: runIndex,
287490
287556
  fromChar: chunkStartChar,
@@ -287516,7 +287582,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287516
287582
  toChar: wordEndNoSpace,
287517
287583
  width: wordOnlyWidth,
287518
287584
  maxFontSize: lineHeightFontSize(run2),
287519
- maxFontInfo: getFontInfoFromRun(run2),
287585
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287520
287586
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
287521
287587
  segments: [{
287522
287588
  runIndex,
@@ -287584,7 +287650,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287584
287650
  toChar: wordEndNoSpace,
287585
287651
  width: wordOnlyWidth,
287586
287652
  maxFontSize: lineHeightFontSize(run2),
287587
- maxFontInfo: getFontInfoFromRun(run2),
287653
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287588
287654
  maxWidth: getEffectiveWidth(bodyContentWidth),
287589
287655
  segments: [{
287590
287656
  runIndex,
@@ -287610,7 +287676,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287610
287676
  if (shouldIncludeDelimiterSpace && currentLine.width + boundarySpacing + wordOnlyWidth + spaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX$1) {
287611
287677
  currentLine.toChar = wordEndNoSpace;
287612
287678
  currentLine.width = roundValue(currentLine.width + boundarySpacing + wordOnlyWidth);
287613
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
287679
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
287614
287680
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
287615
287681
  let explicitXHere;
287616
287682
  if (inActiveTabGroup && activeTabGroup) {
@@ -287646,7 +287712,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287646
287712
  if (compressedWidth != null)
287647
287713
  currentLine.naturalWidth = roundValue(totalWidthWithWord);
287648
287714
  currentLine.width = roundValue(targetWidth);
287649
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
287715
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
287650
287716
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
287651
287717
  appendSegment(currentLine.segments, runIndex, wordStartChar, newToChar, wordCommitWidth, explicitX, wordIndex === 0 ? consumeSegmentPrecedingTabEndX() : undefined);
287652
287718
  if (shouldIncludeDelimiterSpace)
@@ -287676,7 +287742,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287676
287742
  toChar: charPosInRun,
287677
287743
  width: 0,
287678
287744
  maxFontSize: lineHeightFontSize(run2),
287679
- maxFontInfo: getFontInfoFromRun(run2),
287745
+ maxFontInfo: getFontInfoFromRun(run2, fontContext),
287680
287746
  maxWidth: getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : bodyContentWidth),
287681
287747
  segments: [],
287682
287748
  spaceCount: 0
@@ -287692,7 +287758,7 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287692
287758
  currentLine.width = roundValue(currentLine.width + tabAdvance);
287693
287759
  if (stop?.source === "explicit")
287694
287760
  currentLine.hasExplicitTabStops = true;
287695
- currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
287761
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2, fontContext);
287696
287762
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, lineHeightFontSize(run2));
287697
287763
  currentLine.toRun = runIndex;
287698
287764
  currentLine.toChar = charPosInRun;
@@ -287756,9 +287822,9 @@ async function measureParagraphBlock(block, maxWidth, resolvePhysical = resolveP
287756
287822
  ...dropCapMeasure ? { dropCap: dropCapMeasure } : {}
287757
287823
  };
287758
287824
  }
287759
- async function measureTableBlock(block, constraints, resolvePhysical = resolvePhysicalFamily) {
287825
+ async function measureTableBlock(block, constraints, fontContext) {
287760
287826
  const workingInput = buildAutoFitWorkingGridInput(block, { maxWidth: typeof constraints === "number" ? constraints : constraints.maxWidth });
287761
- const columnWidths = await resolveRuntimeTableColumnWidths(block, workingInput);
287827
+ const columnWidths = await resolveRuntimeTableColumnWidths(block, workingInput, fontContext);
287762
287828
  const gridColumnCount = columnWidths.length;
287763
287829
  const calculateCellWidth = (startCol, colspan) => {
287764
287830
  let width = 0;
@@ -287809,7 +287875,7 @@ async function measureTableBlock(block, constraints, resolvePhysical = resolvePh
287809
287875
  const measure = await measureBlock(block$1, {
287810
287876
  maxWidth: contentWidth$1,
287811
287877
  maxHeight: Infinity
287812
- }, resolvePhysical);
287878
+ }, fontContext);
287813
287879
  blockMeasures.push(measure);
287814
287880
  const blockHeight = "totalHeight" in measure ? measure.totalHeight : ("height" in measure) ? measure.height : 0;
287815
287881
  if ((block$1.kind === "image" || block$1.kind === "drawing") && block$1.anchor?.isAnchored === true && (block$1.wrap?.type ?? "Inline") !== "Inline")
@@ -287897,14 +287963,15 @@ async function measureTableBlock(block, constraints, resolvePhysical = resolvePh
287897
287963
  tableBorderWidths: borderWidthH > 0 || borderWidthV > 0 ? tableBorderWidths : undefined
287898
287964
  };
287899
287965
  }
287900
- async function resolveRuntimeTableColumnWidths(block, workingInput) {
287966
+ async function resolveRuntimeTableColumnWidths(block, workingInput, fontContext) {
287901
287967
  const fixedLayout = computeFixedTableColumnWidths(workingInput);
287902
287968
  if (workingInput.layoutMode === "fixed")
287903
287969
  return fixedLayout.columnWidths;
287904
- const { contentMetrics, cellMetricKeys } = await buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout);
287970
+ const { contentMetrics, cellMetricKeys } = await buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout, fontContext);
287905
287971
  const cacheKey = buildAutoFitTableResultCacheKey(block, {
287906
287972
  maxWidth: workingInput.maxTableWidth,
287907
287973
  cellMetricKeys,
287974
+ fontSignature: fontContext.fontSignature,
287908
287975
  workingInput,
287909
287976
  fixedLayout
287910
287977
  });
@@ -287922,8 +287989,9 @@ async function resolveRuntimeTableColumnWidths(block, workingInput) {
287922
287989
  });
287923
287990
  return result.columnWidths;
287924
287991
  }
287925
- async function buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout) {
287926
- const contentMetrics = await measureTableAutoFitContentMetrics(block, workingInput, fixedLayout, measureBlock);
287992
+ async function buildMeasuredAutoFitContentMetrics(block, workingInput, fixedLayout, fontContext) {
287993
+ const measureBlockWithFontContext = (childBlock, childConstraints) => measureBlock(childBlock, childConstraints, fontContext);
287994
+ const contentMetrics = await measureTableAutoFitContentMetrics(block, workingInput, fixedLayout, measureBlockWithFontContext, fontContext);
287927
287995
  return {
287928
287996
  contentMetrics,
287929
287997
  cellMetricKeys: contentMetrics.cellMetricKeys
@@ -288037,7 +288105,7 @@ function normalizeConstraints(constraints) {
288037
288105
  return { maxWidth: constraints };
288038
288106
  return constraints;
288039
288107
  }
288040
- async function measureListBlock(block, constraints, resolvePhysical = resolvePhysicalFamily) {
288108
+ async function measureListBlock(block, constraints, fontContext) {
288041
288109
  const ctx$1 = getCanvasContext();
288042
288110
  const items = [];
288043
288111
  let totalHeight = 0;
@@ -288056,12 +288124,12 @@ async function measureListBlock(block, constraints, resolvePhysical = resolvePhy
288056
288124
  bold: marker.run.bold,
288057
288125
  italic: marker.run.italic,
288058
288126
  letterSpacing: marker.run.letterSpacing
288059
- }, resolvePhysical);
288127
+ }, fontContext);
288060
288128
  markerTextWidth = marker.markerText ? measureText(marker.markerText, markerFont, ctx$1) : 0;
288061
288129
  markerWidth = 0;
288062
288130
  indentLeft = wordLayout.indentLeftPx ?? 0;
288063
288131
  } else {
288064
- const { font: markerFont } = buildFontString(getPrimaryRun(item.paragraph), resolvePhysical);
288132
+ const { font: markerFont } = buildFontString(getPrimaryRun(item.paragraph), fontContext);
288065
288133
  const markerText = item.marker.text ?? "";
288066
288134
  markerTextWidth = markerText ? measureText(markerText, markerFont, ctx$1) : 0;
288067
288135
  indentLeft = resolveIndentLeft(item);
@@ -288069,7 +288137,7 @@ async function measureListBlock(block, constraints, resolvePhysical = resolvePhy
288069
288137
  markerWidth = Math.max(24, markerTextWidth + 8, indentHanging);
288070
288138
  }
288071
288139
  const paragraphWidth = Math.max(1, constraints.maxWidth - indentLeft - markerWidth);
288072
- const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth, resolvePhysical);
288140
+ const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth, fontContext);
288073
288141
  totalHeight += paragraphMeasure.totalHeight;
288074
288142
  items.push({
288075
288143
  itemId: item.id,
@@ -288085,7 +288153,7 @@ async function measureListBlock(block, constraints, resolvePhysical = resolvePhy
288085
288153
  totalHeight
288086
288154
  };
288087
288155
  }
288088
- async function layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, deps, fontResolver) {
288156
+ async function layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, deps, fontResolver, hasFace, effectiveSignature) {
288089
288157
  deps.headerLayoutsByRId.clear();
288090
288158
  deps.footerLayoutsByRId.clear();
288091
288159
  if (!headerFooterInput)
@@ -288108,27 +288176,30 @@ async function layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetad
288108
288176
  };
288109
288177
  };
288110
288178
  if (sectionMetadata.length > 1 && sectionMetadata.some((s2) => s2.margins || s2.pageSize)) {
288111
- await layoutWithPerSectionConstraints("header", headerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.headerLayoutsByRId, fontResolver);
288112
- await layoutWithPerSectionConstraints("footer", footerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.footerLayoutsByRId, fontResolver);
288179
+ await layoutWithPerSectionConstraints("header", headerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.headerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
288180
+ await layoutWithPerSectionConstraints("footer", footerBlocksByRId, sectionMetadata, constraints, pageResolver, deps.footerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
288113
288181
  } else {
288114
288182
  const effectiveHeaderRefsBySection = buildEffectiveHeaderFooterRefsBySection(sectionMetadata, "header");
288115
288183
  const effectiveFooterRefsBySection = buildEffectiveHeaderFooterRefsBySection(sectionMetadata, "footer");
288116
- await layoutBlocksByRId("header", headerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveHeaderRefsBySection), constraints, pageResolver, deps.headerLayoutsByRId, fontResolver);
288117
- await layoutBlocksByRId("footer", footerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveFooterRefsBySection), constraints, pageResolver, deps.footerLayoutsByRId, fontResolver);
288184
+ await layoutBlocksByRId("header", headerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveHeaderRefsBySection), constraints, pageResolver, deps.headerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
288185
+ await layoutBlocksByRId("footer", footerBlocksByRId, collectReferencedHeaderFooterRIds(effectiveFooterRefsBySection), constraints, pageResolver, deps.footerLayoutsByRId, fontResolver, hasFace, effectiveSignature);
288118
288186
  }
288119
288187
  }
288120
- async function layoutBlocksByRId(kind, blocksByRId, referencedRIds, constraints, pageResolver, layoutsByRId, fontResolver) {
288188
+ async function layoutBlocksByRId(kind, blocksByRId, referencedRIds, constraints, pageResolver, layoutsByRId, fontResolver, hasFace, effectiveSignature) {
288121
288189
  if (!blocksByRId || referencedRIds.size === 0)
288122
288190
  return;
288123
- const resolvePhysical = fontResolver ? (css) => fontResolver.resolvePhysicalFamily(css) : undefined;
288124
- const fontSignature = fontResolver?.signature ?? "";
288191
+ const fontSignature = effectiveSignature ?? "";
288192
+ const fontMeasureContext = fontResolver ? {
288193
+ resolvePhysical: (css, face) => hasFace ? fontResolver.resolvePhysicalFamilyForFace(css, face, hasFace) : fontResolver.resolvePhysicalFamily(css),
288194
+ fontSignature
288195
+ } : undefined;
288125
288196
  for (const [rId, blocks2] of blocksByRId) {
288126
288197
  if (!referencedRIds.has(rId))
288127
288198
  continue;
288128
288199
  if (!blocks2 || blocks2.length === 0)
288129
288200
  continue;
288130
288201
  try {
288131
- const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, (block, c) => measureBlock(block, c, resolvePhysical), undefined, undefined, pageResolver, kind, fontSignature);
288202
+ const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature);
288132
288203
  if (batchResult.default)
288133
288204
  layoutsByRId.set(rId, {
288134
288205
  kind,
@@ -288174,18 +288245,21 @@ function adjustFramePositionsForContentWidth(layout, blocks2, effectiveWidth, co
288174
288245
  fragment2.x -= widthDiff / 2;
288175
288246
  }
288176
288247
  }
288177
- async function layoutWithPerSectionConstraints(kind, blocksByRId, sectionMetadata, fallbackConstraints, pageResolver, layoutsByRId, fontResolver) {
288248
+ async function layoutWithPerSectionConstraints(kind, blocksByRId, sectionMetadata, fallbackConstraints, pageResolver, layoutsByRId, fontResolver, hasFace, effectiveSignature) {
288178
288249
  if (!blocksByRId)
288179
288250
  return;
288180
- const resolvePhysical = fontResolver ? (css) => fontResolver.resolvePhysicalFamily(css) : undefined;
288181
- const fontSignature = fontResolver?.signature ?? "";
288251
+ const fontSignature = effectiveSignature ?? "";
288252
+ const fontMeasureContext = fontResolver ? {
288253
+ resolvePhysical: (css, face) => hasFace ? fontResolver.resolvePhysicalFamilyForFace(css, face, hasFace) : fontResolver.resolvePhysicalFamily(css),
288254
+ fontSignature
288255
+ } : undefined;
288182
288256
  const groups = buildSectionAwareHeaderFooterMeasurementGroups(kind, blocksByRId, sectionMetadata, fallbackConstraints);
288183
288257
  for (const group of groups) {
288184
288258
  const blocks2 = blocksByRId.get(group.rId);
288185
288259
  if (!blocks2 || blocks2.length === 0)
288186
288260
  continue;
288187
288261
  try {
288188
- const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, (block, c) => measureBlock(block, c, resolvePhysical), undefined, undefined, pageResolver, kind, fontSignature);
288262
+ const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature);
288189
288263
  if (batchResult.default)
288190
288264
  for (const sectionIndex of group.sectionIndices) {
288191
288265
  const contentWidth = buildSectionContentWidth(sectionMetadata.find((s2) => s2.sectionIndex === sectionIndex), fallbackConstraints);
@@ -288835,80 +288909,146 @@ function defaultInvalidate() {
288835
288909
  clearTextMeasurementCaches();
288836
288910
  measureCache.clear();
288837
288911
  }
288838
- function faceKey(req) {
288839
- return `${req.family.toLowerCase()}|${req.weight}|${req.style}`;
288912
+ function toCssFontSource(url2) {
288913
+ return /^\s*url\(/i.test(url2) ? url2 : `url(${JSON.stringify(url2)})`;
288914
+ }
288915
+ function defaultScheduleMicrotask(callback) {
288916
+ if (typeof queueMicrotask === "function") {
288917
+ queueMicrotask(callback);
288918
+ return;
288919
+ }
288920
+ Promise.resolve().then(callback);
288921
+ }
288922
+ function primaryFamily(css) {
288923
+ const comma = css.indexOf(",");
288924
+ return (comma === -1 ? css : css.slice(0, comma)).trim().replace(/^["']|["']$/g, "");
288840
288925
  }
288841
- function collect(out, node3, resolve3) {
288926
+ function makeResolveFace(resolver2, hasFace) {
288927
+ if (resolver2 && hasFace)
288928
+ return (logical, face) => {
288929
+ const r$1 = resolver2.resolveFace(logical, face, hasFace);
288930
+ return {
288931
+ physicalFamily: r$1.physicalFamily,
288932
+ reason: r$1.reason
288933
+ };
288934
+ };
288935
+ if (resolver2)
288936
+ return (logical) => {
288937
+ const r$1 = resolver2.resolveFontFamily(logical);
288938
+ return {
288939
+ physicalFamily: r$1.physicalFamily,
288940
+ reason: r$1.reason
288941
+ };
288942
+ };
288943
+ return (logical) => {
288944
+ const r$1 = resolveFontFamily2(logical);
288945
+ return {
288946
+ physicalFamily: r$1.physicalFamily,
288947
+ reason: r$1.reason
288948
+ };
288949
+ };
288950
+ }
288951
+ function collect(acc, node3, resolveFace$1) {
288842
288952
  if (!node3 || typeof node3.fontFamily !== "string" || !node3.fontFamily)
288843
288953
  return;
288844
- const family$1 = resolve3(node3.fontFamily);
288845
- if (!family$1)
288954
+ const weight = node3.bold === true ? "700" : "400";
288955
+ const style2 = node3.italic === true ? "italic" : "normal";
288956
+ const logicalPrimary = primaryFamily(node3.fontFamily);
288957
+ if (!logicalPrimary)
288846
288958
  return;
288847
- const req = {
288848
- family: family$1,
288849
- weight: node3.bold === true ? "700" : "400",
288850
- style: node3.italic === true ? "italic" : "normal"
288851
- };
288852
- const key2 = faceKey(req);
288853
- if (!out.has(key2))
288854
- out.set(key2, req);
288959
+ const usedKey = `${logicalPrimary.toLowerCase()}|${weight}|${style2}`;
288960
+ if (acc.usedFaces.has(usedKey))
288961
+ return;
288962
+ const { physicalFamily, reason } = resolveFace$1(node3.fontFamily, {
288963
+ weight,
288964
+ style: style2
288965
+ });
288966
+ acc.usedFaces.set(usedKey, {
288967
+ logicalFamily: logicalPrimary,
288968
+ weight,
288969
+ style: style2
288970
+ });
288971
+ acc.sigEntries.set(usedKey, [
288972
+ logicalPrimary.toLowerCase(),
288973
+ weight,
288974
+ style2,
288975
+ (physicalFamily || "").toLowerCase(),
288976
+ reason
288977
+ ]);
288978
+ if (physicalFamily) {
288979
+ const reqKey = `${physicalFamily.toLowerCase()}|${weight}|${style2}`;
288980
+ if (!acc.requiredFaces.has(reqKey))
288981
+ acc.requiredFaces.set(reqKey, {
288982
+ family: physicalFamily,
288983
+ weight,
288984
+ style: style2
288985
+ });
288986
+ }
288855
288987
  }
288856
- function collectRuns(out, runs2, resolve3) {
288988
+ function collectRuns(acc, runs2, resolveFace$1) {
288857
288989
  if (!runs2)
288858
288990
  return;
288859
288991
  for (const run2 of runs2) {
288860
288992
  const bearing = run2;
288861
288993
  if (run2.kind === "fieldAnnotation" && (typeof bearing.fontFamily !== "string" || !bearing.fontFamily))
288862
- collect(out, {
288994
+ collect(acc, {
288863
288995
  ...bearing,
288864
288996
  fontFamily: "Arial"
288865
- }, resolve3);
288997
+ }, resolveFace$1);
288866
288998
  else
288867
- collect(out, bearing, resolve3);
288999
+ collect(acc, bearing, resolveFace$1);
288868
289000
  }
288869
289001
  }
288870
- function collectParagraph(out, paragraph2, resolve3) {
289002
+ function collectParagraph(acc, paragraph2, resolveFace$1) {
288871
289003
  if (!paragraph2)
288872
289004
  return;
288873
- collectRuns(out, paragraph2.runs, resolve3);
288874
- collect(out, paragraph2.attrs?.wordLayout?.marker?.run, resolve3);
288875
- collect(out, paragraph2.attrs?.dropCapDescriptor?.run, resolve3);
289005
+ collectRuns(acc, paragraph2.runs, resolveFace$1);
289006
+ collect(acc, paragraph2.attrs?.wordLayout?.marker?.run, resolveFace$1);
289007
+ collect(acc, paragraph2.attrs?.dropCapDescriptor?.run, resolveFace$1);
288876
289008
  }
288877
- function collectTable(out, table2, resolve3) {
289009
+ function collectTable(acc, table2, resolveFace$1) {
288878
289010
  for (const row2 of table2.rows)
288879
289011
  for (const cell2 of row2.cells) {
288880
- collectParagraph(out, cell2.paragraph, resolve3);
289012
+ collectParagraph(acc, cell2.paragraph, resolveFace$1);
288881
289013
  if (cell2.blocks)
288882
289014
  for (const b$1 of cell2.blocks)
288883
- collectBlock(out, b$1, resolve3);
289015
+ collectBlock(acc, b$1, resolveFace$1);
288884
289016
  }
288885
289017
  }
288886
- function collectList(out, list5, resolve3) {
289018
+ function collectList(acc, list5, resolveFace$1) {
288887
289019
  for (const item of list5.items)
288888
- collectParagraph(out, item.paragraph, resolve3);
289020
+ collectParagraph(acc, item.paragraph, resolveFace$1);
288889
289021
  }
288890
- function collectBlock(out, block, resolve3) {
289022
+ function collectBlock(acc, block, resolveFace$1) {
288891
289023
  switch (block.kind) {
288892
289024
  case "paragraph":
288893
- collectParagraph(out, block, resolve3);
289025
+ collectParagraph(acc, block, resolveFace$1);
288894
289026
  break;
288895
289027
  case "table":
288896
- collectTable(out, block, resolve3);
289028
+ collectTable(acc, block, resolveFace$1);
288897
289029
  break;
288898
289030
  case "list":
288899
- collectList(out, block, resolve3);
289031
+ collectList(acc, block, resolveFace$1);
288900
289032
  break;
288901
289033
  default:
288902
289034
  break;
288903
289035
  }
288904
289036
  }
288905
- function planRequiredFontFaces(blocks2, resolver2) {
288906
- const resolve3 = resolver2 ? (family$1) => resolver2.resolvePrimaryPhysicalFamily(family$1) : resolvePrimaryPhysicalFamily;
288907
- const out = /* @__PURE__ */ new Map;
289037
+ function planFontFaces(blocks2, resolver2, hasFace) {
289038
+ const resolveFace$1 = makeResolveFace(resolver2, hasFace);
289039
+ const acc = {
289040
+ requiredFaces: /* @__PURE__ */ new Map,
289041
+ usedFaces: /* @__PURE__ */ new Map,
289042
+ sigEntries: /* @__PURE__ */ new Map
289043
+ };
288908
289044
  if (blocks2)
288909
289045
  for (const block of blocks2)
288910
- collectBlock(out, block, resolve3);
288911
- return [...out.values()];
289046
+ collectBlock(acc, block, resolveFace$1);
289047
+ return {
289048
+ requiredFaces: [...acc.requiredFaces.values()],
289049
+ usedFaces: [...acc.usedFaces.values()],
289050
+ effectiveSignature: acc.sigEntries.size === 0 ? "" : JSON.stringify([...acc.sigEntries.entries()].sort(([a2], [b$1]) => a2 < b$1 ? -1 : a2 > b$1 ? 1 : 0).map(([, tuple]) => tuple))
289051
+ };
288912
289052
  }
288913
289053
  function buildSemanticFootnoteBlocks(input2, footnotesMode) {
288914
289054
  if (!input2 || input2.refs.length === 0 || input2.blocksById.size === 0)
@@ -309988,7 +310128,407 @@ menclose::after {
309988
310128
  const minReadablePx = getMinimumReadableTextStartPx(markerContentEndPx, gutterWidthPx);
309989
310129
  return Math.max(nextTabStopPx, minReadablePx);
309990
310130
  }
309991
- }, hashParagraphBorder$2 = (border) => {
310131
+ }, SETTLED_STATUSES, BUNDLED_SUBSTITUTES, FontResolver = class {
310132
+ #overrides = /* @__PURE__ */ new Map;
310133
+ #version = 0;
310134
+ #cachedSignature = null;
310135
+ map(logicalFamily, physicalFamily) {
310136
+ const key2 = normalizeFamilyKey$2(logicalFamily);
310137
+ const physical = physicalFamily?.trim();
310138
+ if (!key2 || !physical)
310139
+ return;
310140
+ if (this.#overrides.get(key2) === physical)
310141
+ return;
310142
+ if ((BUNDLED_SUBSTITUTES[key2] ?? logicalFamily.trim()) === physical) {
310143
+ if (this.#overrides.delete(key2)) {
310144
+ this.#version += 1;
310145
+ this.#cachedSignature = null;
310146
+ }
310147
+ return;
310148
+ }
310149
+ this.#overrides.set(key2, physical);
310150
+ this.#version += 1;
310151
+ this.#cachedSignature = null;
310152
+ }
310153
+ unmap(logicalFamily) {
310154
+ if (this.#overrides.delete(normalizeFamilyKey$2(logicalFamily))) {
310155
+ this.#version += 1;
310156
+ this.#cachedSignature = null;
310157
+ }
310158
+ }
310159
+ reset() {
310160
+ if (this.#overrides.size === 0)
310161
+ return;
310162
+ this.#overrides.clear();
310163
+ this.#version += 1;
310164
+ this.#cachedSignature = null;
310165
+ }
310166
+ get version() {
310167
+ return this.#version;
310168
+ }
310169
+ get signature() {
310170
+ if (this.#cachedSignature !== null)
310171
+ return this.#cachedSignature;
310172
+ this.#cachedSignature = this.#overrides.size === 0 ? "" : JSON.stringify([...this.#overrides.entries()].sort(([a2], [b$1]) => a2 < b$1 ? -1 : a2 > b$1 ? 1 : 0));
310173
+ return this.#cachedSignature;
310174
+ }
310175
+ #physicalFor(bareFamily) {
310176
+ const key2 = normalizeFamilyKey$2(bareFamily);
310177
+ const override = this.#overrides.get(key2);
310178
+ if (override)
310179
+ return {
310180
+ physical: override,
310181
+ reason: "custom_mapping"
310182
+ };
310183
+ const bundled = BUNDLED_SUBSTITUTES[key2];
310184
+ if (bundled)
310185
+ return {
310186
+ physical: bundled,
310187
+ reason: "bundled_substitute"
310188
+ };
310189
+ return {
310190
+ physical: bareFamily,
310191
+ reason: "as_requested"
310192
+ };
310193
+ }
310194
+ resolveFontFamily(logicalFamily) {
310195
+ const primary = splitStack(logicalFamily)[0] ?? logicalFamily;
310196
+ const { physical, reason } = this.#physicalFor(primary);
310197
+ return {
310198
+ logicalFamily,
310199
+ physicalFamily: physical,
310200
+ reason
310201
+ };
310202
+ }
310203
+ resolvePhysicalFamily(cssFontFamily) {
310204
+ if (!cssFontFamily)
310205
+ return cssFontFamily;
310206
+ const parts = splitStack(cssFontFamily);
310207
+ if (parts.length === 0)
310208
+ return cssFontFamily;
310209
+ const { physical, reason } = this.#physicalFor(parts[0]);
310210
+ if (reason === "as_requested")
310211
+ return cssFontFamily;
310212
+ return [physical, ...parts.slice(1)].join(", ");
310213
+ }
310214
+ resolveFace(logicalFamily, face, hasFace) {
310215
+ const primary = splitStack(logicalFamily)[0] ?? logicalFamily;
310216
+ const { physical, reason } = this.#physicalFor(primary);
310217
+ if (reason === "as_requested")
310218
+ return {
310219
+ logicalFamily,
310220
+ physicalFamily: physical,
310221
+ reason
310222
+ };
310223
+ if (hasFace(physical, face.weight, face.style))
310224
+ return {
310225
+ logicalFamily,
310226
+ physicalFamily: physical,
310227
+ reason
310228
+ };
310229
+ return {
310230
+ logicalFamily,
310231
+ physicalFamily: primary,
310232
+ reason: "fallback_face_absent"
310233
+ };
310234
+ }
310235
+ resolvePhysicalFamilyForFace(cssFontFamily, face, hasFace) {
310236
+ if (!cssFontFamily)
310237
+ return cssFontFamily;
310238
+ const parts = splitStack(cssFontFamily);
310239
+ if (parts.length === 0)
310240
+ return cssFontFamily;
310241
+ const { physical, reason } = this.#physicalFor(parts[0]);
310242
+ if (reason === "as_requested")
310243
+ return cssFontFamily;
310244
+ if (!hasFace(physical, face.weight, face.style))
310245
+ return cssFontFamily;
310246
+ return [physical, ...parts.slice(1)].join(", ");
310247
+ }
310248
+ resolvePrimaryPhysicalFamily(family$1) {
310249
+ const primary = splitStack(family$1)[0] ?? family$1;
310250
+ return this.#physicalFor(primary).physical;
310251
+ }
310252
+ resolvePhysicalFamilies(families) {
310253
+ const out = /* @__PURE__ */ new Set;
310254
+ for (const family$1 of families)
310255
+ if (family$1)
310256
+ out.add(this.resolvePrimaryPhysicalFamily(family$1));
310257
+ return [...out];
310258
+ }
310259
+ }, defaultResolver, DEFAULT_FONT_MEASURE_CONTEXT, fontConfigVersion = 0, BUNDLED_MANIFEST, defaultAssetBase = "/fonts/", installedRegistries, DEFAULT_FONT_LOAD_TIMEOUT_MS = 3000, DEFAULT_PROBE_SIZE = "16px", FontRegistry = class {
310260
+ #fontSet;
310261
+ #FontFaceCtor;
310262
+ #probeSize;
310263
+ #scheduleTimeout;
310264
+ #cancelTimeout;
310265
+ #managed = /* @__PURE__ */ new Map;
310266
+ #status = /* @__PURE__ */ new Map;
310267
+ #sources = /* @__PURE__ */ new Map;
310268
+ #warnedFailures = /* @__PURE__ */ new Set;
310269
+ #inflight = /* @__PURE__ */ new Map;
310270
+ #faceStatus = /* @__PURE__ */ new Map;
310271
+ #faceInflight = /* @__PURE__ */ new Map;
310272
+ #faceSources = /* @__PURE__ */ new Map;
310273
+ #facesByFamily = /* @__PURE__ */ new Map;
310274
+ #warnedFaceFailures = /* @__PURE__ */ new Set;
310275
+ constructor(options = {}) {
310276
+ this.#fontSet = options.fontSet ?? null;
310277
+ this.#FontFaceCtor = options.FontFaceCtor ?? null;
310278
+ this.#probeSize = options.probeSize ?? DEFAULT_PROBE_SIZE;
310279
+ this.#scheduleTimeout = options.scheduleTimeout ?? ((cb, ms) => globalThis.setTimeout(cb, ms));
310280
+ this.#cancelTimeout = options.cancelTimeout ?? ((handle3) => globalThis.clearTimeout(handle3));
310281
+ }
310282
+ register(descriptor) {
310283
+ const { family: family$1, source, descriptors: descriptors2 } = descriptor;
310284
+ const identitySource = typeof source === "string" ? canonicalizeFontSource(source) : source;
310285
+ const key2 = faceKeyOf$1(family$1, normalizeWeight(descriptors2?.weight), normalizeStyle$1(descriptors2?.style));
310286
+ if (typeof identitySource === "string") {
310287
+ const existingSource = this.#faceSources.get(key2);
310288
+ if (existingSource === identitySource)
310289
+ return {
310290
+ family: family$1,
310291
+ status: this.getStatus(family$1),
310292
+ changed: false
310293
+ };
310294
+ if (existingSource !== undefined)
310295
+ throw new Error(`[superdoc] font face "${key2}" is already registered from a different source ("${existingSource}"); a registered face's source cannot be replaced`);
310296
+ }
310297
+ if (this.#FontFaceCtor && this.#fontSet) {
310298
+ const face = new this.#FontFaceCtor(family$1, source, descriptors2);
310299
+ this.#fontSet.add(face);
310300
+ this.#managed.set(family$1, face);
310301
+ }
310302
+ if (typeof source === "string") {
310303
+ const list5 = this.#sources.get(family$1) ?? [];
310304
+ if (!list5.includes(source))
310305
+ list5.push(source);
310306
+ this.#sources.set(family$1, list5);
310307
+ }
310308
+ if (!this.#status.has(family$1))
310309
+ this.#status.set(family$1, "unloaded");
310310
+ this.#trackFace(family$1, key2);
310311
+ if (!this.#faceStatus.has(key2))
310312
+ this.#faceStatus.set(key2, "unloaded");
310313
+ if (typeof identitySource === "string" && !this.#faceSources.has(key2))
310314
+ this.#faceSources.set(key2, identitySource);
310315
+ return {
310316
+ family: family$1,
310317
+ status: this.getStatus(family$1),
310318
+ changed: true
310319
+ };
310320
+ }
310321
+ #trackFace(family$1, key2) {
310322
+ const fam = normalizeFamilyKey$1(family$1);
310323
+ const set = this.#facesByFamily.get(fam) ?? /* @__PURE__ */ new Set;
310324
+ set.add(key2);
310325
+ this.#facesByFamily.set(fam, set);
310326
+ }
310327
+ isManaged(family$1) {
310328
+ return this.#managed.has(family$1);
310329
+ }
310330
+ getStatus(family$1) {
310331
+ const statuses = [];
310332
+ const faceKeys = this.#facesByFamily.get(normalizeFamilyKey$1(family$1));
310333
+ if (faceKeys)
310334
+ for (const k$1 of faceKeys)
310335
+ statuses.push(this.#faceStatus.get(k$1) ?? "unloaded");
310336
+ const legacy = this.#status.get(family$1);
310337
+ if (legacy)
310338
+ statuses.push(legacy);
310339
+ if (statuses.length === 0)
310340
+ return "unloaded";
310341
+ for (const s2 of [
310342
+ "failed",
310343
+ "timed_out",
310344
+ "fallback_used",
310345
+ "loaded",
310346
+ "loading",
310347
+ "unloaded"
310348
+ ])
310349
+ if (statuses.includes(s2))
310350
+ return s2;
310351
+ return "unloaded";
310352
+ }
310353
+ hasFace(family$1, weight, style2) {
310354
+ return this.#facesByFamily.get(normalizeFamilyKey$1(family$1))?.has(faceKeyOf$1(family$1, weight, style2)) ?? false;
310355
+ }
310356
+ isAvailable(family$1) {
310357
+ if (!this.#fontSet)
310358
+ return false;
310359
+ try {
310360
+ return this.#fontSet.check(`${this.#probeSize} ${quoteFamily(family$1)}`);
310361
+ } catch {
310362
+ return false;
310363
+ }
310364
+ }
310365
+ awaitFace(family$1, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
310366
+ if (this.#status.get(family$1) === "loaded")
310367
+ return Promise.resolve({
310368
+ family: family$1,
310369
+ status: "loaded"
310370
+ });
310371
+ const existing = this.#inflight.get(family$1);
310372
+ if (existing)
310373
+ return existing;
310374
+ const probe = this.#loadOne(family$1, timeoutMs).finally(() => {
310375
+ this.#inflight.delete(family$1);
310376
+ });
310377
+ this.#inflight.set(family$1, probe);
310378
+ return probe;
310379
+ }
310380
+ async awaitFaces(families, options = {}) {
310381
+ const unique$2 = [...new Set(families)];
310382
+ const timeoutMs = options.timeoutMs ?? 3000;
310383
+ return Promise.all(unique$2.map((family$1) => this.awaitFace(family$1, timeoutMs)));
310384
+ }
310385
+ getRequiredFaces(families, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
310386
+ return [...new Set(families)].map((family$1) => ({
310387
+ family: family$1,
310388
+ status: this.getStatus(family$1),
310389
+ ready: this.awaitFace(family$1, timeoutMs)
310390
+ }));
310391
+ }
310392
+ getStates() {
310393
+ return [...this.#status.entries()].map(([family$1, status]) => ({
310394
+ family: family$1,
310395
+ status
310396
+ }));
310397
+ }
310398
+ getFaceStatus(request) {
310399
+ return this.#faceStatus.get(faceKeyOf$1(request.family, request.weight, request.style)) ?? "unloaded";
310400
+ }
310401
+ awaitFaceRequest(request, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
310402
+ const key2 = faceKeyOf$1(request.family, request.weight, request.style);
310403
+ if (this.#faceStatus.get(key2) === "loaded")
310404
+ return Promise.resolve({
310405
+ request,
310406
+ status: "loaded"
310407
+ });
310408
+ const existing = this.#faceInflight.get(key2);
310409
+ if (existing)
310410
+ return existing;
310411
+ const probe = this.#loadOneFace(request, key2, timeoutMs).finally(() => {
310412
+ this.#faceInflight.delete(key2);
310413
+ });
310414
+ this.#faceInflight.set(key2, probe);
310415
+ return probe;
310416
+ }
310417
+ async awaitFaceRequests(requests, options = {}) {
310418
+ const timeoutMs = options.timeoutMs ?? 3000;
310419
+ const seen = /* @__PURE__ */ new Set;
310420
+ const unique$2 = [];
310421
+ for (const r$1 of requests) {
310422
+ const key2 = faceKeyOf$1(r$1.family, r$1.weight, r$1.style);
310423
+ if (seen.has(key2))
310424
+ continue;
310425
+ seen.add(key2);
310426
+ unique$2.push(r$1);
310427
+ }
310428
+ return Promise.all(unique$2.map((r$1) => this.awaitFaceRequest(r$1, timeoutMs)));
310429
+ }
310430
+ async#loadOneFace(request, key2, timeoutMs) {
310431
+ this.#trackFace(request.family, key2);
310432
+ const fontSet = this.#fontSet;
310433
+ if (!fontSet) {
310434
+ this.#faceStatus.set(key2, "fallback_used");
310435
+ return {
310436
+ request,
310437
+ status: "fallback_used"
310438
+ };
310439
+ }
310440
+ this.#faceStatus.set(key2, "loading");
310441
+ const probe = faceProbe(request.family, request.weight, request.style, this.#probeSize);
310442
+ const TIMEOUT = Symbol("timeout");
310443
+ let handle3;
310444
+ const timeout$1 = new Promise((resolve3) => {
310445
+ handle3 = this.#scheduleTimeout(() => resolve3(TIMEOUT), timeoutMs);
310446
+ });
310447
+ try {
310448
+ const settled = await Promise.race([fontSet.load(probe), timeout$1]);
310449
+ if (settled === TIMEOUT) {
310450
+ this.#faceStatus.set(key2, "timed_out");
310451
+ return {
310452
+ request,
310453
+ status: "timed_out"
310454
+ };
310455
+ }
310456
+ const status = settled.length > 0 ? "loaded" : "fallback_used";
310457
+ this.#faceStatus.set(key2, status);
310458
+ return {
310459
+ request,
310460
+ status
310461
+ };
310462
+ } catch {
310463
+ this.#faceStatus.set(key2, "failed");
310464
+ this.#warnFaceFailureOnce(request, key2);
310465
+ return {
310466
+ request,
310467
+ status: "failed"
310468
+ };
310469
+ } finally {
310470
+ this.#cancelTimeout(handle3);
310471
+ }
310472
+ }
310473
+ #warnFaceFailureOnce(request, key2) {
310474
+ if (this.#warnedFaceFailures.has(key2))
310475
+ return;
310476
+ this.#warnedFaceFailures.add(key2);
310477
+ const src = this.#faceSources.get(key2);
310478
+ const detail = src ? ` from ${src}` : "";
310479
+ 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.`);
310480
+ }
310481
+ async#loadOne(family$1, timeoutMs) {
310482
+ const fontSet = this.#fontSet;
310483
+ if (!fontSet) {
310484
+ this.#status.set(family$1, "fallback_used");
310485
+ return {
310486
+ family: family$1,
310487
+ status: "fallback_used"
310488
+ };
310489
+ }
310490
+ this.#status.set(family$1, "loading");
310491
+ const probe = `${this.#probeSize} ${quoteFamily(family$1)}`;
310492
+ const TIMEOUT = Symbol("timeout");
310493
+ let handle3;
310494
+ const timeout$1 = new Promise((resolve3) => {
310495
+ handle3 = this.#scheduleTimeout(() => resolve3(TIMEOUT), timeoutMs);
310496
+ });
310497
+ try {
310498
+ const settled = await Promise.race([fontSet.load(probe), timeout$1]);
310499
+ if (settled === TIMEOUT) {
310500
+ this.#status.set(family$1, "timed_out");
310501
+ return {
310502
+ family: family$1,
310503
+ status: "timed_out"
310504
+ };
310505
+ }
310506
+ const status = settled.length > 0 ? "loaded" : "fallback_used";
310507
+ this.#status.set(family$1, status);
310508
+ return {
310509
+ family: family$1,
310510
+ status
310511
+ };
310512
+ } catch {
310513
+ this.#status.set(family$1, "failed");
310514
+ this.#warnLoadFailureOnce(family$1);
310515
+ return {
310516
+ family: family$1,
310517
+ status: "failed"
310518
+ };
310519
+ } finally {
310520
+ this.#cancelTimeout(handle3);
310521
+ }
310522
+ }
310523
+ #warnLoadFailureOnce(family$1) {
310524
+ if (this.#warnedFailures.has(family$1))
310525
+ return;
310526
+ this.#warnedFailures.add(family$1);
310527
+ const sources = this.#sources.get(family$1);
310528
+ const detail = sources && sources.length ? ` from ${sources.join(", ")}` : "";
310529
+ console.warn(`[superdoc] font asset failed to load for "${family$1}"${detail}. Check fonts.assetBaseUrl / fonts.resolveAssetUrl so the bundled .woff2 are served.`);
310530
+ }
310531
+ }, registriesByFontSet, domlessRegistry = null, hashParagraphBorder$2 = (border) => {
309992
310532
  const parts = [];
309993
310533
  if (border.style !== undefined)
309994
310534
  parts.push(`s:${border.style}`);
@@ -310305,7 +310845,7 @@ menclose::after {
310305
310845
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0)
310306
310846
  return;
310307
310847
  return value;
310308
- }, 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) => {
310848
+ }, 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)) => {
310309
310849
  const markerContainer = doc$12.createElement("span");
310310
310850
  markerContainer.classList.add(DOM_CLASS_NAMES.LIST_MARKER);
310311
310851
  markerContainer.style.display = "inline-block";
@@ -310314,7 +310854,11 @@ menclose::after {
310314
310854
  markerEl.classList.add("superdoc-paragraph-marker");
310315
310855
  markerEl.textContent = markerText;
310316
310856
  markerEl.style.pointerEvents = "none";
310317
- markerEl.style.fontFamily = toCssFontFamily(run2.fontFamily) ?? run2.fontFamily ?? "";
310857
+ const cssFontFamily = toCssFontFamily(run2.fontFamily) ?? run2.fontFamily ?? "";
310858
+ markerEl.style.fontFamily = resolvePhysical(cssFontFamily, {
310859
+ weight: run2.bold ? "700" : "400",
310860
+ style: run2.italic ? "italic" : "normal"
310861
+ });
310318
310862
  if (run2.fontSize != null)
310319
310863
  markerEl.style.fontSize = `${run2.fontSize}px`;
310320
310864
  markerEl.style.fontWeight = run2.bold ? "bold" : "";
@@ -310332,7 +310876,7 @@ menclose::after {
310332
310876
  applySourceAnchorDataset(markerEl, sourceAnchor);
310333
310877
  return markerContainer;
310334
310878
  }, renderLegacyListMarker = (params$1) => {
310335
- const { doc: doc$12, lineEl, wordLayout, markerLayout, markerMeasure, markerTextWidthPx, indentLeftPx, hangingIndentPx, firstLineIndentPx, isRtl, sourceAnchor } = params$1;
310879
+ const { doc: doc$12, lineEl, wordLayout, markerLayout, markerMeasure, markerTextWidthPx, indentLeftPx, hangingIndentPx, firstLineIndentPx, isRtl, sourceAnchor, resolvePhysical = (css) => resolvePhysicalFamily(css) } = params$1;
310336
310880
  const markerTextWidth = markerTextWidthPx ?? markerMeasure?.markerTextWidth ?? 0;
310337
310881
  const markerGeometry = markerLayout?.justification === "left" && wordLayout?.firstLineIndentMode !== true && typeof markerTextWidth === "number" && Number.isFinite(markerTextWidth) && markerTextWidth >= 0 ? resolvePainterListMarkerGeometry({
310338
310882
  wordLayout,
@@ -310369,7 +310913,7 @@ menclose::after {
310369
310913
  lineEl.style.paddingLeft = `${anchorPoint}px`;
310370
310914
  if (markerLayout?.run?.vanish)
310371
310915
  return;
310372
- const markerContainer = createListMarkerElement(doc$12, markerLayout?.markerText ?? "", markerLayout?.run ?? {}, sourceAnchor);
310916
+ const markerContainer = createListMarkerElement(doc$12, markerLayout?.markerText ?? "", markerLayout?.run ?? {}, sourceAnchor, resolvePhysical);
310373
310917
  markerContainer.style.position = "relative";
310374
310918
  if (markerJustification === "right") {
310375
310919
  markerContainer.style.position = "absolute";
@@ -310390,14 +310934,14 @@ menclose::after {
310390
310934
  prependMarkerSuffix(doc$12, lineEl, isMarkerSuffix(suffix) ? suffix : undefined, suffixWidthPx, markerLayout?.run?.fontSize);
310391
310935
  lineEl.prepend(markerContainer);
310392
310936
  }, renderResolvedListMarker = (params$1) => {
310393
- const { doc: doc$12, lineEl, marker, isRtl, sourceAnchor } = params$1;
310937
+ const { doc: doc$12, lineEl, marker, isRtl, sourceAnchor, resolvePhysical } = params$1;
310394
310938
  if (isRtl)
310395
310939
  lineEl.style.paddingRight = `${marker.firstLinePaddingLeftPx}px`;
310396
310940
  else
310397
310941
  lineEl.style.paddingLeft = `${marker.firstLinePaddingLeftPx}px`;
310398
310942
  if (marker.vanish)
310399
310943
  return;
310400
- const markerContainer = createListMarkerElement(doc$12, marker.text, marker.run, marker.sourceAnchor ?? sourceAnchor);
310944
+ const markerContainer = createListMarkerElement(doc$12, marker.text, marker.run, marker.sourceAnchor ?? sourceAnchor, resolvePhysical);
310401
310945
  markerContainer.style.position = "relative";
310402
310946
  if (marker.justification === "right") {
310403
310947
  markerContainer.style.position = "absolute";
@@ -310665,7 +311209,7 @@ menclose::after {
310665
311209
  skipJustifyOverride: (resolvedLine?.skipJustify ?? false) || hasMultipleExplicitPositionedSegments
310666
311210
  }) ? Math.max(lineWidth, availableWidth) : lineWidth;
310667
311211
  }, renderResolvedLines = (params$1) => {
310668
- const { frameEl, block, resolvedContent: content3, markerTextWidth, renderLine: renderLine$1, captureLineSnapshot, convertFinalParagraphMark, lineTopOffset = 0, sourceAnchor } = params$1;
311212
+ const { frameEl, block, resolvedContent: content3, markerTextWidth, renderLine: renderLine$1, captureLineSnapshot, convertFinalParagraphMark, lineTopOffset = 0, sourceAnchor, resolvePhysical = (css) => resolvePhysicalFamily(css) } = params$1;
310669
311213
  const renderedLines = [];
310670
311214
  const resolvedMarker = content3.marker;
310671
311215
  const expandedRunsForBlock = expandRunsForInlineNewlines(block.runs);
@@ -310695,7 +311239,8 @@ menclose::after {
310695
311239
  lineEl,
310696
311240
  marker: resolvedMarker,
310697
311241
  isRtl,
310698
- sourceAnchor
311242
+ sourceAnchor,
311243
+ resolvePhysical
310699
311244
  });
310700
311245
  if (convertFinalParagraphMark && index2 === content3.lines.length - 1 && !content3.continuesOnNext)
310701
311246
  convertParagraphMarkToCellMark(lineEl);
@@ -310718,7 +311263,7 @@ menclose::after {
310718
311263
  renderedLines
310719
311264
  };
310720
311265
  }, renderMeasuredLines = (params$1) => {
310721
- 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;
311266
+ 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;
310722
311267
  const lines = linesOverride ?? measure.lines ?? [];
310723
311268
  const paraIndent = block.attrs?.indent;
310724
311269
  const paraIndentLeft = paraIndent?.left ?? 0;
@@ -310792,7 +311337,8 @@ menclose::after {
310792
311337
  hangingIndentPx: markerHanging,
310793
311338
  firstLineIndentPx: markerFirstLine,
310794
311339
  isRtl,
310795
- sourceAnchor
311340
+ sourceAnchor,
311341
+ resolvePhysical
310796
311342
  });
310797
311343
  } else
310798
311344
  applyParagraphLineIndentation({
@@ -310946,7 +311492,7 @@ menclose::after {
310946
311492
  hasSdtContainerChrome
310947
311493
  };
310948
311494
  }, renderTableCell = (deps) => {
310949
- 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;
311495
+ 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;
310950
311496
  const padding = cell2?.attrs?.padding || {
310951
311497
  top: 0,
310952
311498
  left: 4,
@@ -311198,6 +311744,7 @@ menclose::after {
311198
311744
  },
311199
311745
  contentControlsChrome: chrome2,
311200
311746
  applySdtDataset: applySdtDataset$1,
311747
+ resolvePhysical,
311201
311748
  renderLine: ({ block: block$1, line, lineIndex, isLastLine, resolvedListTextStartPx }) => renderLine$1(block$1, line, {
311202
311749
  ...context,
311203
311750
  section: "body"
@@ -311374,7 +311921,7 @@ menclose::after {
311374
311921
  left: baseBorders.left
311375
311922
  };
311376
311923
  }, renderTableRow = (deps) => {
311377
- 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;
311924
+ 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;
311378
311925
  const totalCols = columnWidths.length;
311379
311926
  const calculateXPosition = (gridColumnStart) => {
311380
311927
  let x = cellSpacingPx;
@@ -311461,12 +312008,13 @@ menclose::after {
311461
312008
  tableIndent,
311462
312009
  isRtl,
311463
312010
  cellWidth: computedCellWidth > 0 ? computedCellWidth : undefined,
311464
- chrome: chrome2
312011
+ chrome: chrome2,
312012
+ resolvePhysical
311465
312013
  });
311466
312014
  container.appendChild(cellElement);
311467
312015
  }
311468
312016
  }, renderTableFragment = (deps) => {
311469
- const { doc: doc$12, fragment: fragment2, 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;
312017
+ const { doc: doc$12, fragment: fragment2, 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;
311470
312018
  if (!doc$12) {
311471
312019
  console.error("DomPainter: document is not available");
311472
312020
  if (typeof document !== "undefined") {
@@ -311648,7 +312196,8 @@ menclose::after {
311648
312196
  chrome: chrome2,
311649
312197
  continuesFromPrev: false,
311650
312198
  continuesOnNext: false,
311651
- cellSpacingPx
312199
+ cellSpacingPx,
312200
+ resolvePhysical
311652
312201
  });
311653
312202
  y$1 += rowMeasure.height + cellSpacingPx;
311654
312203
  }
@@ -311766,7 +312315,8 @@ menclose::after {
311766
312315
  continuesFromPrev: isFirstRenderedBodyRow && fragment2.continuesFromPrev === true,
311767
312316
  continuesOnNext: isLastRenderedBodyRow && fragment2.continuesOnNext === true,
311768
312317
  partialRow: partialRowData,
311769
- cellSpacingPx
312318
+ cellSpacingPx,
312319
+ resolvePhysical
311770
312320
  });
311771
312321
  y$1 += actualRowHeight + cellSpacingPx;
311772
312322
  }
@@ -311984,7 +312534,7 @@ menclose::after {
311984
312534
  else
311985
312535
  delete el.dataset.continuesOnNext;
311986
312536
  }, isMinimalWordLayout$2 = (value) => isMinimalWordLayout(value), renderParagraphFragment = (params$1) => {
311987
- const { doc: doc$12, fragment: fragment2, sdtBoundary, betweenInfo, resolvedItem, applyStyles: applyStyles$3, applyResolvedFragmentFrame, applyFragmentFrame, applySdtDataset: applySdtDataset$1, applyContainerSdtDataset: applyContainerSdtDataset$1, renderLine: renderLine$1, captureLineSnapshot, createErrorPlaceholder, contentControlsChrome } = params$1;
312537
+ const { doc: doc$12, fragment: fragment2, 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;
311988
312538
  try {
311989
312539
  if (!doc$12)
311990
312540
  throw new Error("DomPainter: document is not available");
@@ -312043,7 +312593,8 @@ menclose::after {
312043
312593
  sdtBoundary,
312044
312594
  applySdtDataset: applySdtDataset$1,
312045
312595
  applyContainerSdtDataset: applyContainerSdtDataset$1,
312046
- renderDropCap: (descriptor, dropCapMeasure) => renderDropCap(doc$12, descriptor, dropCapMeasure),
312596
+ resolvePhysical,
312597
+ renderDropCap: (descriptor, dropCapMeasure) => renderDropCap(doc$12, descriptor, dropCapMeasure, resolvePhysical),
312047
312598
  renderLine: renderLine$1,
312048
312599
  captureLineSnapshot: (lineEl, options) => {
312049
312600
  captureLineSnapshot(lineEl, {
@@ -312062,12 +312613,15 @@ menclose::after {
312062
312613
  });
312063
312614
  return createErrorPlaceholder(fragment2.blockId, error3);
312064
312615
  }
312065
- }, renderDropCap = (doc$12, descriptor, measure) => {
312616
+ }, renderDropCap = (doc$12, descriptor, measure, resolvePhysical = (css) => resolvePhysicalFamily(css)) => {
312066
312617
  const { run: run2, mode } = descriptor;
312067
312618
  const dropCapEl = doc$12.createElement("span");
312068
312619
  dropCapEl.classList.add("superdoc-drop-cap");
312069
312620
  dropCapEl.textContent = run2.text;
312070
- dropCapEl.style.fontFamily = run2.fontFamily;
312621
+ dropCapEl.style.fontFamily = resolvePhysical(run2.fontFamily, {
312622
+ weight: run2.bold ? "700" : "400",
312623
+ style: run2.italic ? "italic" : "normal"
312624
+ });
312071
312625
  dropCapEl.style.fontSize = `${run2.fontSize}px`;
312072
312626
  if (run2.bold)
312073
312627
  dropCapEl.style.fontWeight = "bold";
@@ -312160,344 +312714,7 @@ menclose::after {
312160
312714
  const visualTextEndOffset = lineEl.dir === "rtl" || lineEl.style.direction === "rtl" ? alignmentOffset : alignmentOffset + lineWidth;
312161
312715
  mark2.style.left = `${Math.max(0, leftOffsetPx + visualTextEndOffset)}px`;
312162
312716
  lineEl.appendChild(mark2);
312163
- }, SETTLED_STATUSES, BUNDLED_SUBSTITUTES, FontResolver = class {
312164
- #overrides = /* @__PURE__ */ new Map;
312165
- #version = 0;
312166
- map(logicalFamily, physicalFamily) {
312167
- const key2 = normalizeFamilyKey$2(logicalFamily);
312168
- const physical = physicalFamily?.trim();
312169
- if (!key2 || !physical)
312170
- return;
312171
- if (this.#overrides.get(key2) === physical)
312172
- return;
312173
- this.#overrides.set(key2, physical);
312174
- this.#version += 1;
312175
- }
312176
- unmap(logicalFamily) {
312177
- if (this.#overrides.delete(normalizeFamilyKey$2(logicalFamily)))
312178
- this.#version += 1;
312179
- }
312180
- reset() {
312181
- if (this.#overrides.size === 0)
312182
- return;
312183
- this.#overrides.clear();
312184
- this.#version += 1;
312185
- }
312186
- get version() {
312187
- return this.#version;
312188
- }
312189
- get signature() {
312190
- if (this.#overrides.size === 0)
312191
- return "";
312192
- return JSON.stringify([...this.#overrides.entries()].sort(([a2], [b$1]) => a2 < b$1 ? -1 : a2 > b$1 ? 1 : 0));
312193
- }
312194
- #physicalFor(bareFamily) {
312195
- const key2 = normalizeFamilyKey$2(bareFamily);
312196
- const override = this.#overrides.get(key2);
312197
- if (override)
312198
- return {
312199
- physical: override,
312200
- reason: "custom_mapping"
312201
- };
312202
- const bundled = BUNDLED_SUBSTITUTES[key2];
312203
- if (bundled)
312204
- return {
312205
- physical: bundled,
312206
- reason: "bundled_substitute"
312207
- };
312208
- return {
312209
- physical: bareFamily,
312210
- reason: "as_requested"
312211
- };
312212
- }
312213
- resolveFontFamily(logicalFamily) {
312214
- const primary = splitStack(logicalFamily)[0] ?? logicalFamily;
312215
- const { physical, reason } = this.#physicalFor(primary);
312216
- return {
312217
- logicalFamily,
312218
- physicalFamily: physical,
312219
- reason
312220
- };
312221
- }
312222
- resolvePhysicalFamily(cssFontFamily) {
312223
- if (!cssFontFamily)
312224
- return cssFontFamily;
312225
- const parts = splitStack(cssFontFamily);
312226
- if (parts.length === 0)
312227
- return cssFontFamily;
312228
- const { physical, reason } = this.#physicalFor(parts[0]);
312229
- if (reason === "as_requested")
312230
- return cssFontFamily;
312231
- return [physical, ...parts.slice(1)].join(", ");
312232
- }
312233
- resolvePrimaryPhysicalFamily(family$1) {
312234
- const primary = splitStack(family$1)[0] ?? family$1;
312235
- return this.#physicalFor(primary).physical;
312236
- }
312237
- resolvePhysicalFamilies(families) {
312238
- const out = /* @__PURE__ */ new Set;
312239
- for (const family$1 of families)
312240
- if (family$1)
312241
- out.add(this.resolvePrimaryPhysicalFamily(family$1));
312242
- return [...out];
312243
- }
312244
- }, defaultResolver, fontConfigVersion = 0, BUNDLED_MANIFEST, defaultAssetBase = "/fonts/", installedRegistries, DEFAULT_FONT_LOAD_TIMEOUT_MS = 3000, DEFAULT_PROBE_SIZE = "16px", FontRegistry = class {
312245
- #fontSet;
312246
- #FontFaceCtor;
312247
- #probeSize;
312248
- #scheduleTimeout;
312249
- #cancelTimeout;
312250
- #managed = /* @__PURE__ */ new Map;
312251
- #status = /* @__PURE__ */ new Map;
312252
- #sources = /* @__PURE__ */ new Map;
312253
- #warnedFailures = /* @__PURE__ */ new Set;
312254
- #inflight = /* @__PURE__ */ new Map;
312255
- #faceStatus = /* @__PURE__ */ new Map;
312256
- #faceInflight = /* @__PURE__ */ new Map;
312257
- #faceSources = /* @__PURE__ */ new Map;
312258
- #facesByFamily = /* @__PURE__ */ new Map;
312259
- #warnedFaceFailures = /* @__PURE__ */ new Set;
312260
- constructor(options = {}) {
312261
- this.#fontSet = options.fontSet ?? null;
312262
- this.#FontFaceCtor = options.FontFaceCtor ?? null;
312263
- this.#probeSize = options.probeSize ?? DEFAULT_PROBE_SIZE;
312264
- this.#scheduleTimeout = options.scheduleTimeout ?? ((cb, ms) => globalThis.setTimeout(cb, ms));
312265
- this.#cancelTimeout = options.cancelTimeout ?? ((handle3) => globalThis.clearTimeout(handle3));
312266
- }
312267
- register(descriptor) {
312268
- const { family: family$1, source, descriptors: descriptors2 } = descriptor;
312269
- if (this.#FontFaceCtor && this.#fontSet) {
312270
- const face = new this.#FontFaceCtor(family$1, source, descriptors2);
312271
- this.#fontSet.add(face);
312272
- this.#managed.set(family$1, face);
312273
- }
312274
- if (typeof source === "string") {
312275
- const list5 = this.#sources.get(family$1) ?? [];
312276
- if (!list5.includes(source))
312277
- list5.push(source);
312278
- this.#sources.set(family$1, list5);
312279
- }
312280
- if (!this.#status.has(family$1))
312281
- this.#status.set(family$1, "unloaded");
312282
- const key2 = faceKeyOf$1(family$1, normalizeWeight(descriptors2?.weight), normalizeStyle$1(descriptors2?.style));
312283
- this.#trackFace(family$1, key2);
312284
- if (!this.#faceStatus.has(key2))
312285
- this.#faceStatus.set(key2, "unloaded");
312286
- if (typeof source === "string" && !this.#faceSources.has(key2))
312287
- this.#faceSources.set(key2, source);
312288
- return {
312289
- family: family$1,
312290
- status: this.getStatus(family$1)
312291
- };
312292
- }
312293
- #trackFace(family$1, key2) {
312294
- const fam = normalizeFamilyKey$1(family$1);
312295
- const set = this.#facesByFamily.get(fam) ?? /* @__PURE__ */ new Set;
312296
- set.add(key2);
312297
- this.#facesByFamily.set(fam, set);
312298
- }
312299
- isManaged(family$1) {
312300
- return this.#managed.has(family$1);
312301
- }
312302
- getStatus(family$1) {
312303
- const statuses = [];
312304
- const faceKeys = this.#facesByFamily.get(normalizeFamilyKey$1(family$1));
312305
- if (faceKeys)
312306
- for (const k$1 of faceKeys)
312307
- statuses.push(this.#faceStatus.get(k$1) ?? "unloaded");
312308
- const legacy = this.#status.get(family$1);
312309
- if (legacy)
312310
- statuses.push(legacy);
312311
- if (statuses.length === 0)
312312
- return "unloaded";
312313
- for (const s2 of [
312314
- "failed",
312315
- "timed_out",
312316
- "fallback_used",
312317
- "loaded",
312318
- "loading",
312319
- "unloaded"
312320
- ])
312321
- if (statuses.includes(s2))
312322
- return s2;
312323
- return "unloaded";
312324
- }
312325
- isAvailable(family$1) {
312326
- if (!this.#fontSet)
312327
- return false;
312328
- try {
312329
- return this.#fontSet.check(`${this.#probeSize} ${quoteFamily(family$1)}`);
312330
- } catch {
312331
- return false;
312332
- }
312333
- }
312334
- awaitFace(family$1, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
312335
- if (this.#status.get(family$1) === "loaded")
312336
- return Promise.resolve({
312337
- family: family$1,
312338
- status: "loaded"
312339
- });
312340
- const existing = this.#inflight.get(family$1);
312341
- if (existing)
312342
- return existing;
312343
- const probe = this.#loadOne(family$1, timeoutMs).finally(() => {
312344
- this.#inflight.delete(family$1);
312345
- });
312346
- this.#inflight.set(family$1, probe);
312347
- return probe;
312348
- }
312349
- async awaitFaces(families, options = {}) {
312350
- const unique$2 = [...new Set(families)];
312351
- const timeoutMs = options.timeoutMs ?? 3000;
312352
- return Promise.all(unique$2.map((family$1) => this.awaitFace(family$1, timeoutMs)));
312353
- }
312354
- getRequiredFaces(families, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
312355
- return [...new Set(families)].map((family$1) => ({
312356
- family: family$1,
312357
- status: this.getStatus(family$1),
312358
- ready: this.awaitFace(family$1, timeoutMs)
312359
- }));
312360
- }
312361
- getStates() {
312362
- return [...this.#status.entries()].map(([family$1, status]) => ({
312363
- family: family$1,
312364
- status
312365
- }));
312366
- }
312367
- getFaceStatus(request) {
312368
- return this.#faceStatus.get(faceKeyOf$1(request.family, request.weight, request.style)) ?? "unloaded";
312369
- }
312370
- awaitFaceRequest(request, timeoutMs = DEFAULT_FONT_LOAD_TIMEOUT_MS) {
312371
- const key2 = faceKeyOf$1(request.family, request.weight, request.style);
312372
- if (this.#faceStatus.get(key2) === "loaded")
312373
- return Promise.resolve({
312374
- request,
312375
- status: "loaded"
312376
- });
312377
- const existing = this.#faceInflight.get(key2);
312378
- if (existing)
312379
- return existing;
312380
- const probe = this.#loadOneFace(request, key2, timeoutMs).finally(() => {
312381
- this.#faceInflight.delete(key2);
312382
- });
312383
- this.#faceInflight.set(key2, probe);
312384
- return probe;
312385
- }
312386
- async awaitFaceRequests(requests, options = {}) {
312387
- const timeoutMs = options.timeoutMs ?? 3000;
312388
- const seen = /* @__PURE__ */ new Set;
312389
- const unique$2 = [];
312390
- for (const r$1 of requests) {
312391
- const key2 = faceKeyOf$1(r$1.family, r$1.weight, r$1.style);
312392
- if (seen.has(key2))
312393
- continue;
312394
- seen.add(key2);
312395
- unique$2.push(r$1);
312396
- }
312397
- return Promise.all(unique$2.map((r$1) => this.awaitFaceRequest(r$1, timeoutMs)));
312398
- }
312399
- async#loadOneFace(request, key2, timeoutMs) {
312400
- this.#trackFace(request.family, key2);
312401
- const fontSet = this.#fontSet;
312402
- if (!fontSet) {
312403
- this.#faceStatus.set(key2, "fallback_used");
312404
- return {
312405
- request,
312406
- status: "fallback_used"
312407
- };
312408
- }
312409
- this.#faceStatus.set(key2, "loading");
312410
- const probe = faceProbe(request.family, request.weight, request.style, this.#probeSize);
312411
- const TIMEOUT = Symbol("timeout");
312412
- let handle3;
312413
- const timeout$1 = new Promise((resolve3) => {
312414
- handle3 = this.#scheduleTimeout(() => resolve3(TIMEOUT), timeoutMs);
312415
- });
312416
- try {
312417
- const settled = await Promise.race([fontSet.load(probe), timeout$1]);
312418
- if (settled === TIMEOUT) {
312419
- this.#faceStatus.set(key2, "timed_out");
312420
- return {
312421
- request,
312422
- status: "timed_out"
312423
- };
312424
- }
312425
- const status = settled.length > 0 ? "loaded" : "fallback_used";
312426
- this.#faceStatus.set(key2, status);
312427
- return {
312428
- request,
312429
- status
312430
- };
312431
- } catch {
312432
- this.#faceStatus.set(key2, "failed");
312433
- this.#warnFaceFailureOnce(request, key2);
312434
- return {
312435
- request,
312436
- status: "failed"
312437
- };
312438
- } finally {
312439
- this.#cancelTimeout(handle3);
312440
- }
312441
- }
312442
- #warnFaceFailureOnce(request, key2) {
312443
- if (this.#warnedFaceFailures.has(key2))
312444
- return;
312445
- this.#warnedFaceFailures.add(key2);
312446
- const src = this.#faceSources.get(key2);
312447
- const detail = src ? ` from ${src}` : "";
312448
- 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.`);
312449
- }
312450
- async#loadOne(family$1, timeoutMs) {
312451
- const fontSet = this.#fontSet;
312452
- if (!fontSet) {
312453
- this.#status.set(family$1, "fallback_used");
312454
- return {
312455
- family: family$1,
312456
- status: "fallback_used"
312457
- };
312458
- }
312459
- this.#status.set(family$1, "loading");
312460
- const probe = `${this.#probeSize} ${quoteFamily(family$1)}`;
312461
- const TIMEOUT = Symbol("timeout");
312462
- let handle3;
312463
- const timeout$1 = new Promise((resolve3) => {
312464
- handle3 = this.#scheduleTimeout(() => resolve3(TIMEOUT), timeoutMs);
312465
- });
312466
- try {
312467
- const settled = await Promise.race([fontSet.load(probe), timeout$1]);
312468
- if (settled === TIMEOUT) {
312469
- this.#status.set(family$1, "timed_out");
312470
- return {
312471
- family: family$1,
312472
- status: "timed_out"
312473
- };
312474
- }
312475
- const status = settled.length > 0 ? "loaded" : "fallback_used";
312476
- this.#status.set(family$1, status);
312477
- return {
312478
- family: family$1,
312479
- status
312480
- };
312481
- } catch {
312482
- this.#status.set(family$1, "failed");
312483
- this.#warnLoadFailureOnce(family$1);
312484
- return {
312485
- family: family$1,
312486
- status: "failed"
312487
- };
312488
- } finally {
312489
- this.#cancelTimeout(handle3);
312490
- }
312491
- }
312492
- #warnLoadFailureOnce(family$1) {
312493
- if (this.#warnedFailures.has(family$1))
312494
- return;
312495
- this.#warnedFailures.add(family$1);
312496
- const sources = this.#sources.get(family$1);
312497
- const detail = sources && sources.length ? ` from ${sources.join(", ")}` : "";
312498
- console.warn(`[superdoc] font asset failed to load for "${family$1}"${detail}. Check fonts.assetBaseUrl / fonts.resolveAssetUrl so the bundled .woff2 are served.`);
312499
- }
312500
- }, 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) => {
312717
+ }, 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) => {
312501
312718
  if (hasVerticalPositioning(run2))
312502
312719
  element3.style.lineHeight = "1";
312503
312720
  const explicitBaselineShift = normalizeBaselineShift(run2.baselineShift);
@@ -312520,7 +312737,10 @@ menclose::after {
312520
312737
  }, applyRunStyles = (element3, run2, _isLink = false, resolvePhysical = resolvePhysicalFamily) => {
312521
312738
  if (run2.kind === "tab" || run2.kind === "image" || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" || run2.kind === "math")
312522
312739
  return;
312523
- element3.style.fontFamily = resolvePhysical(run2.fontFamily);
312740
+ element3.style.fontFamily = resolvePhysical(run2.fontFamily, {
312741
+ weight: run2.bold ? "700" : "400",
312742
+ style: run2.italic ? "italic" : "normal"
312743
+ });
312524
312744
  element3.style.fontSize = `${run2.fontSize}px`;
312525
312745
  if (run2.bold)
312526
312746
  element3.style.fontWeight = "bold";
@@ -312701,8 +312921,13 @@ menclose::after {
312701
312921
  annotation.style.height = `${run2.size.height}px`;
312702
312922
  }
312703
312923
  }
312704
- if (run2.fontFamily)
312705
- annotation.style.fontFamily = run2.fontFamily;
312924
+ {
312925
+ const resolvePhysical = context.resolvePhysical ?? resolvePhysicalFamily;
312926
+ annotation.style.fontFamily = resolvePhysical(run2.fontFamily || "Arial, sans-serif", {
312927
+ weight: run2.bold ? "700" : "400",
312928
+ style: run2.italic ? "italic" : "normal"
312929
+ });
312930
+ }
312706
312931
  {
312707
312932
  const fontSize = run2.fontSize ? typeof run2.fontSize === "number" ? `${run2.fontSize}pt` : run2.fontSize : BROWSER_DEFAULT_FONT_SIZE;
312708
312933
  annotation.style.fontSize = fontSize;
@@ -315413,6 +315638,7 @@ menclose::after {
315413
315638
  applyFragmentFrame: (el, paraFragment) => this.applyFragmentFrame(el, paraFragment, context.section, context.story),
315414
315639
  applySdtDataset,
315415
315640
  applyContainerSdtDataset,
315641
+ resolvePhysical: this.options.resolvePhysical,
315416
315642
  renderLine: ({ block, line, availableWidth, lineIndex, skipJustify, preExpandedRuns, resolvedListTextStartPx, indentOffsetOverride, paragraphMarkLeftOffsetOverride }) => this.renderLine(block, line, context, availableWidth, lineIndex, skipJustify, preExpandedRuns, resolvedListTextStartPx, indentOffsetOverride, paragraphMarkLeftOffsetOverride),
315417
315643
  captureLineSnapshot: (lineEl, options) => {
315418
315644
  this.capturePaintSnapshotLine(lineEl, context, {
@@ -316185,7 +316411,8 @@ menclose::after {
316185
316411
  applyFragmentFrame: applyFragmentFrameWithSection,
316186
316412
  applySdtDataset,
316187
316413
  applyContainerSdtDataset,
316188
- applyStyles
316414
+ applyStyles,
316415
+ resolvePhysical: this.options.resolvePhysical
316189
316416
  });
316190
316417
  if (resolvedItem) {
316191
316418
  this.applyResolvedFragmentFrame(el, resolvedItem, fragment2, context.section, context.story);
@@ -323661,14 +323888,14 @@ menclose::after {
323661
323888
  if (value === ",")
323662
323889
  return ",";
323663
323890
  return DEFAULT_DECIMAL_SEPARATOR2;
323664
- }, DROP_CAP_PADDING_PX = 4, measureDropCap = (ctx$1, descriptor, spacing, resolvePhysical = resolvePhysicalFamily) => {
323891
+ }, DROP_CAP_PADDING_PX = 4, measureDropCap = (ctx$1, descriptor, spacing, fontContext) => {
323665
323892
  const { run: run2, lines, mode } = descriptor;
323666
323893
  const { font } = buildFontString({
323667
323894
  fontFamily: run2.fontFamily,
323668
323895
  fontSize: run2.fontSize,
323669
323896
  bold: run2.bold,
323670
323897
  italic: run2.italic
323671
- }, resolvePhysical);
323898
+ }, fontContext);
323672
323899
  ctx$1.font = font;
323673
323900
  const displayText = applyTextTransform(run2.text, run2);
323674
323901
  const metrics = ctx$1.measureText(displayText);
@@ -324631,11 +324858,11 @@ menclose::after {
324631
324858
  #resolveResult(result, storyId) {
324632
324859
  return resolveResult(result, storyId, this.#options.getFontSignature?.() ?? "");
324633
324860
  }
324634
- async layoutPerRId(headerFooterInput, layout, sectionMetadata, fontResolver) {
324861
+ async layoutPerRId(headerFooterInput, layout, sectionMetadata, fontResolver, hasFace, effectiveSignature) {
324635
324862
  await layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata, {
324636
324863
  headerLayoutsByRId: this.#headerLayoutsByRId,
324637
324864
  footerLayoutsByRId: this.#footerLayoutsByRId
324638
- }, fontResolver);
324865
+ }, fontResolver, hasFace, effectiveSignature);
324639
324866
  this.#resolvedHeaderByRId.clear();
324640
324867
  for (const [key2, result] of this.#headerLayoutsByRId)
324641
324868
  this.#resolvedHeaderByRId.set(key2, this.#resolveResult(result, storyIdFromHeaderFooterLayoutKey(key2)));
@@ -325493,6 +325720,7 @@ menclose::after {
325493
325720
  }, FontReadinessGate = class {
325494
325721
  #getDocumentFonts;
325495
325722
  #getRequiredFaces;
325723
+ #getUsedFaces;
325496
325724
  #resolveFamilies;
325497
325725
  #fontResolver;
325498
325726
  #requestReflow;
@@ -325502,6 +325730,7 @@ menclose::after {
325502
325730
  #timeoutMs;
325503
325731
  #invalidateCaches;
325504
325732
  #context = null;
325733
+ #packInstalledFor = null;
325505
325734
  #fontConfigVersion = 0;
325506
325735
  #requiredSignature = "";
325507
325736
  #requiredFamilies = /* @__PURE__ */ new Set;
@@ -325514,6 +325743,7 @@ menclose::after {
325514
325743
  constructor(options) {
325515
325744
  this.#getDocumentFonts = options.getDocumentFonts;
325516
325745
  this.#getRequiredFaces = options.getRequiredFaces ?? null;
325746
+ this.#getUsedFaces = options.getUsedFaces ?? null;
325517
325747
  this.#fontResolver = options.fontResolver ?? null;
325518
325748
  const resolver2 = this.#fontResolver;
325519
325749
  this.#resolveFamilies = options.resolveFamilies ?? (resolver2 ? (families) => resolver2.resolvePhysicalFamilies(families) : (families) => families);
@@ -325538,13 +325768,19 @@ menclose::after {
325538
325768
  return this.#lastSummary;
325539
325769
  }
325540
325770
  getReport() {
325541
- let logical = [];
325771
+ let declared = [];
325542
325772
  try {
325543
- logical = this.#getDocumentFonts();
325773
+ declared = this.#getDocumentFonts();
325544
325774
  } catch {
325545
325775
  return [];
325546
325776
  }
325547
- return buildFontReport(logical, this.#resolveContext().registry, this.#fontResolver ?? undefined);
325777
+ const registry2 = this.#resolveContext().registry;
325778
+ const resolver2 = this.#fontResolver ?? undefined;
325779
+ const usedFaces = this.#getUsedFaces?.() ?? [];
325780
+ const faceRows = buildFaceReport(usedFaces, registry2, resolver2);
325781
+ const usedFamilies = new Set(usedFaces.map((u) => u.logicalFamily.toLowerCase()));
325782
+ const declaredRows = buildFontReport(declared.filter((family$1) => family$1 && !usedFamilies.has(family$1.toLowerCase())), registry2, resolver2);
325783
+ return [...faceRows, ...declaredRows];
325548
325784
  }
325549
325785
  async ensureReadyForMeasure() {
325550
325786
  if (this.#getRequiredFaces)
@@ -325609,14 +325845,22 @@ menclose::after {
325609
325845
  this.#lastSummary = summarize(results);
325610
325846
  return this.#lastSummary;
325611
325847
  }
325612
- notifyFontConfigChanged() {
325848
+ notifyDocumentFontConfigChanged(options) {
325613
325849
  this.#fontConfigVersion += 1;
325614
- bumpFontConfigVersion();
325615
325850
  this.#resetRequiredAndSeen();
325616
325851
  this.#lateLoadScheduler.cancel();
325617
- this.#invalidateCaches();
325852
+ if (options?.availabilityChanged) {
325853
+ bumpFontConfigVersion();
325854
+ this.#invalidateCaches();
325855
+ }
325618
325856
  this.#requestReflow();
325619
325857
  }
325858
+ invalidateCachesForConfigRegistration() {
325859
+ this.#invalidateCaches();
325860
+ }
325861
+ resolveRegistry() {
325862
+ return this.#resolveContext().registry;
325863
+ }
325620
325864
  resetForDocumentChange() {
325621
325865
  this.#lateLoadScheduler.cancel();
325622
325866
  this.#resetRequiredAndSeen();
@@ -325646,10 +325890,12 @@ menclose::after {
325646
325890
  fontSet,
325647
325891
  registry: registry2
325648
325892
  };
325649
- if (fontSet && this.#onRegistryResolved)
325893
+ if (this.#onRegistryResolved && registry2 !== this.#packInstalledFor) {
325894
+ this.#packInstalledFor = registry2;
325650
325895
  try {
325651
325896
  this.#onRegistryResolved(registry2);
325652
325897
  } catch {}
325898
+ }
325653
325899
  return this.#context;
325654
325900
  }
325655
325901
  #ensureSubscribed() {
@@ -325698,7 +325944,139 @@ menclose::after {
325698
325944
  #flushLateFontLoads() {
325699
325945
  this.#requestReflow();
325700
325946
  }
325701
- }, FACE_STATUS_PRIORITY, DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE, NATIVE_SELECTION_STYLES = `
325947
+ }, FACE_STATUS_PRIORITY, DocumentFontController = class {
325948
+ #resolver;
325949
+ #getGate;
325950
+ #onDocumentFontConfigApplied;
325951
+ #scheduleMicrotask;
325952
+ #runtimeReflowQueued = false;
325953
+ #runtimeReflowToken = 0;
325954
+ #runtimeAvailabilityChanged = false;
325955
+ constructor(deps) {
325956
+ this.#resolver = deps.resolver;
325957
+ this.#getGate = deps.getGate;
325958
+ this.#onDocumentFontConfigApplied = deps.onDocumentFontConfigApplied;
325959
+ this.#scheduleMicrotask = deps.scheduleMicrotask ?? defaultScheduleMicrotask;
325960
+ }
325961
+ map(mappings) {
325962
+ if (this.#applyMappings(mappings))
325963
+ this.#queueRuntimeReflow();
325964
+ }
325965
+ unmap(families) {
325966
+ const before2 = this.#resolver.signature;
325967
+ for (const family$1 of Array.isArray(families) ? families : [families])
325968
+ this.#resolver.unmap(family$1);
325969
+ this.#reflowIfChanged(before2);
325970
+ }
325971
+ reset() {
325972
+ this.#cancelPendingRuntimeReflow();
325973
+ this.#resolver.reset();
325974
+ }
325975
+ dispose() {
325976
+ this.#cancelPendingRuntimeReflow();
325977
+ }
325978
+ applyInitialConfig(config2) {
325979
+ this.#cancelPendingRuntimeReflow();
325980
+ if (!config2)
325981
+ return;
325982
+ const registered$1 = this.#registerFamilies(config2.families);
325983
+ this.#applyMappings(config2.map);
325984
+ if (registered$1)
325985
+ this.#getGate()?.invalidateCachesForConfigRegistration();
325986
+ }
325987
+ add(families) {
325988
+ let committed = false;
325989
+ try {
325990
+ this.#registerFamilies(families, () => {
325991
+ committed = true;
325992
+ });
325993
+ } finally {
325994
+ if (committed) {
325995
+ this.#runtimeAvailabilityChanged = true;
325996
+ this.#queueRuntimeReflow();
325997
+ }
325998
+ }
325999
+ }
326000
+ #registerFamilies(families, onFaceRegistered) {
326001
+ if (!families?.length)
326002
+ return false;
326003
+ const registry2 = this.#getGate()?.resolveRegistry();
326004
+ if (!registry2)
326005
+ throw new Error("[superdoc] fonts.add: the font registry is not ready yet");
326006
+ let changed = false;
326007
+ for (const entry of families) {
326008
+ const family$1 = entry?.family;
326009
+ const faces = entry?.faces;
326010
+ if (typeof family$1 !== "string" || !family$1.trim())
326011
+ throw new Error('[superdoc] fonts.add: each family needs a non-empty "family" name');
326012
+ if (!Array.isArray(faces) || faces.length === 0)
326013
+ throw new Error(`[superdoc] fonts.add: family "${family$1}" needs at least one face in "faces"`);
326014
+ for (const face of faces) {
326015
+ if (!face || typeof face.source !== "string" || !face.source.trim())
326016
+ throw new Error(`[superdoc] fonts.add: family "${family$1}" has a face with no "source" URL`);
326017
+ if (registry2.register({
326018
+ family: family$1,
326019
+ source: toCssFontSource(face.source),
326020
+ descriptors: {
326021
+ weight: face.weight == null ? undefined : String(face.weight),
326022
+ style: face.style
326023
+ }
326024
+ }).changed) {
326025
+ changed = true;
326026
+ onFaceRegistered?.();
326027
+ }
326028
+ }
326029
+ }
326030
+ return changed;
326031
+ }
326032
+ async preload(families) {
326033
+ if (!Array.isArray(families))
326034
+ throw new Error('[superdoc] fonts.preload expects an array of logical family names, e.g. preload(["Georgia"])');
326035
+ const registry2 = this.#getGate()?.resolveRegistry();
326036
+ if (!registry2)
326037
+ throw new Error("[superdoc] fonts.preload: the font registry is not ready yet");
326038
+ const requests = families.map((logical) => ({
326039
+ family: this.#resolver.resolvePrimaryPhysicalFamily(logical),
326040
+ weight: "400",
326041
+ style: "normal"
326042
+ }));
326043
+ await registry2.awaitFaceRequests(requests);
326044
+ }
326045
+ #reflowIfChanged(signatureBefore) {
326046
+ if (this.#resolver.signature !== signatureBefore)
326047
+ this.#queueRuntimeReflow();
326048
+ }
326049
+ #applyMappings(mappings) {
326050
+ if (!mappings)
326051
+ return false;
326052
+ const before2 = this.#resolver.signature;
326053
+ for (const [logicalFamily, physicalFamily] of Object.entries(mappings))
326054
+ this.#resolver.map(logicalFamily, physicalFamily);
326055
+ return this.#resolver.signature !== before2;
326056
+ }
326057
+ #queueRuntimeReflow() {
326058
+ if (this.#runtimeReflowQueued)
326059
+ return;
326060
+ this.#runtimeReflowQueued = true;
326061
+ const token$1 = ++this.#runtimeReflowToken;
326062
+ this.#scheduleMicrotask(() => {
326063
+ if (!this.#runtimeReflowQueued || token$1 !== this.#runtimeReflowToken)
326064
+ return;
326065
+ this.#runtimeReflowQueued = false;
326066
+ const availabilityChanged = this.#runtimeAvailabilityChanged;
326067
+ this.#runtimeAvailabilityChanged = false;
326068
+ this.#onDocumentFontConfigApplied();
326069
+ this.#getGate()?.notifyDocumentFontConfigChanged({ availabilityChanged });
326070
+ });
326071
+ }
326072
+ #cancelPendingRuntimeReflow() {
326073
+ this.#runtimeAvailabilityChanged = false;
326074
+ if (!this.#runtimeReflowQueued)
326075
+ return;
326076
+ this.#runtimeReflowQueued = false;
326077
+ this.#runtimeReflowToken += 1;
326078
+ }
326079
+ }, DEFAULT_SEMANTIC_FOOTNOTE_HEADING_STYLE, NATIVE_SELECTION_STYLES = `
325702
326080
  /* Hide native browser selection on layout engine content.
325703
326081
  * We render our own selection overlay via PresentationEditor's #localSelectionLayer
325704
326082
  * for precise control over selection geometry across pages and zoom levels. */
@@ -325775,7 +326153,7 @@ menclose::after {
325775
326153
  return;
325776
326154
  console.log(...args$1);
325777
326155
  }, 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;
325778
- var init_src_CF4og_LY_es = __esm(() => {
326156
+ var init_src_DvgAvHbj_es = __esm(() => {
325779
326157
  init_rolldown_runtime_Bg48TavK_es();
325780
326158
  init_SuperConverter_B9mZiCO9_es();
325781
326159
  init_jszip_C49i9kUs_es();
@@ -352650,6 +353028,33 @@ function print() { __p += __j.call(arguments, '') }
352650
353028
  "wave",
352651
353029
  "doubleWave"
352652
353030
  ]);
353031
+ SETTLED_STATUSES = [
353032
+ "loaded",
353033
+ "failed",
353034
+ "timed_out",
353035
+ "fallback_used"
353036
+ ];
353037
+ BUNDLED_SUBSTITUTES = Object.freeze({
353038
+ calibri: "Carlito",
353039
+ cambria: "Caladea",
353040
+ arial: "Liberation Sans",
353041
+ "times new roman": "Liberation Serif",
353042
+ "courier new": "Liberation Mono"
353043
+ });
353044
+ defaultResolver = new FontResolver;
353045
+ DEFAULT_FONT_MEASURE_CONTEXT = Object.freeze({
353046
+ resolvePhysical: (cssFontFamily, _face) => resolvePhysicalFamily(cssFontFamily),
353047
+ fontSignature: ""
353048
+ });
353049
+ BUNDLED_MANIFEST = Object.freeze([
353050
+ family("Carlito", "Carlito", "OFL-1.1"),
353051
+ family("Caladea", "Caladea", "Apache-2.0"),
353052
+ family("Liberation Sans", "LiberationSans", "OFL-1.1"),
353053
+ family("Liberation Serif", "LiberationSerif", "OFL-1.1"),
353054
+ family("Liberation Mono", "LiberationMono", "OFL-1.1")
353055
+ ]);
353056
+ installedRegistries = /* @__PURE__ */ new WeakMap;
353057
+ registriesByFontSet = /* @__PURE__ */ new WeakMap;
352653
353058
  PX_PER_PT$12 = 96 / 72;
352654
353059
  BORDER_SIDES3 = [
352655
353060
  "top",
@@ -352681,29 +353086,6 @@ function print() { __p += __j.call(arguments, '') }
352681
353086
  "sdtDocpartId",
352682
353087
  "sdtDocpartInstruction"
352683
353088
  ];
352684
- SETTLED_STATUSES = [
352685
- "loaded",
352686
- "failed",
352687
- "timed_out",
352688
- "fallback_used"
352689
- ];
352690
- BUNDLED_SUBSTITUTES = Object.freeze({
352691
- calibri: "Carlito",
352692
- cambria: "Caladea",
352693
- arial: "Liberation Sans",
352694
- "times new roman": "Liberation Serif",
352695
- "courier new": "Liberation Mono"
352696
- });
352697
- defaultResolver = new FontResolver;
352698
- BUNDLED_MANIFEST = Object.freeze([
352699
- family("Carlito", "Carlito", "OFL-1.1"),
352700
- family("Caladea", "Caladea", "Apache-2.0"),
352701
- family("Liberation Sans", "LiberationSans", "OFL-1.1"),
352702
- family("Liberation Serif", "LiberationSerif", "OFL-1.1"),
352703
- family("Liberation Mono", "LiberationMono", "OFL-1.1")
352704
- ]);
352705
- installedRegistries = /* @__PURE__ */ new WeakMap;
352706
- registriesByFontSet = /* @__PURE__ */ new WeakMap;
352707
353089
  OPERATOR_CHARS = new Set([
352708
353090
  "+",
352709
353091
  "-",
@@ -353936,8 +354318,19 @@ function print() { __p += __j.call(arguments, '') }
353936
354318
  #selectionSync = new SelectionSyncCoordinator;
353937
354319
  #fontGate = null;
353938
354320
  #fontResolver = createFontResolver();
354321
+ #nextFontsChangedSource = null;
354322
+ #fontController = new DocumentFontController({
354323
+ resolver: this.#fontResolver,
354324
+ getGate: () => this.#fontGate,
354325
+ onDocumentFontConfigApplied: () => {
354326
+ this.#nextFontsChangedSource = "config-change";
354327
+ }
354328
+ });
353939
354329
  #fontPlanBlocks = null;
354330
+ #fontPlan = null;
354331
+ #hasFace = (family$1, weight, style2) => this.#fontGate ? this.#fontGate.resolveRegistry().hasFace(family$1, weight, style2) : false;
353940
354332
  #lastFontsChangedKey = null;
354333
+ #lastFontsChangedVersion = -1;
353941
354334
  #lastFontsChangedPayload = null;
353942
354335
  #shouldScrollSelectionIntoView = false;
353943
354336
  #suppressSelectionScrollUntilRaf = false;
@@ -354168,7 +354561,7 @@ function print() { __p += __j.call(arguments, '') }
354168
354561
  initBudgetMs: HEADER_FOOTER_INIT_BUDGET_MS,
354169
354562
  defaultPageSize: DEFAULT_PAGE_SIZE,
354170
354563
  defaultMargins: DEFAULT_MARGINS,
354171
- getFontSignature: () => this.#fontResolver.signature
354564
+ getFontSignature: () => this.#layoutFontSignature
354172
354565
  });
354173
354566
  this.#headerFooterSession.setHoverElements({
354174
354567
  hoverOverlay: this.#hoverOverlay,
@@ -354222,17 +354615,9 @@ function print() { __p += __j.call(arguments, '') }
354222
354615
  getDocumentFonts: () => {
354223
354616
  return this.#editor.converter?.getDocumentFonts?.() ?? [];
354224
354617
  },
354225
- requestReflow: () => {
354226
- this.#layoutState = {
354227
- ...this.#layoutState,
354228
- blocks: [],
354229
- measures: [],
354230
- layout: null
354231
- };
354232
- this.#pendingDocChange = true;
354233
- this.#scheduleRerender();
354234
- },
354235
- getRequiredFaces: () => planRequiredFontFaces(this.#fontPlanBlocks, this.#fontResolver),
354618
+ requestReflow: () => this.#requestFontReflow(),
354619
+ getRequiredFaces: () => this.#fontPlan?.requiredFaces ?? [],
354620
+ getUsedFaces: () => this.#fontPlan?.usedFaces ?? [],
354236
354621
  fontResolver: this.#fontResolver,
354237
354622
  onRegistryResolved: (registry2) => installBundledSubstitutes(registry2, {
354238
354623
  assetBaseUrl: this.#options.fontAssets?.assetBaseUrl,
@@ -354249,6 +354634,7 @@ function print() { __p += __j.call(arguments, '') }
354249
354634
  } : null;
354250
354635
  }
354251
354636
  });
354637
+ this.#fontController.applyInitialConfig(this.#options.fontAssets);
354252
354638
  if (typeof this.#options.disableContextMenu === "boolean")
354253
354639
  this.setContextMenuDisabled(this.#options.disableContextMenu);
354254
354640
  this.#setupHeaderFooterSession();
@@ -355206,18 +355592,46 @@ function print() { __p += __j.call(arguments, '') }
355206
355592
  return this.#fontGate?.getReport() ?? [];
355207
355593
  }
355208
355594
  getMissingFonts() {
355209
- return this.getFontReport().filter((record) => record.missing).map((record) => record.logicalFamily);
355595
+ return [...new Set(this.getFontReport().filter((record) => record.missing).map((record) => record.logicalFamily))];
355596
+ }
355597
+ mapFonts(mappings) {
355598
+ this.#fontController.map(mappings);
355599
+ }
355600
+ unmapFonts(families) {
355601
+ this.#fontController.unmap(families);
355602
+ }
355603
+ addFonts(families) {
355604
+ this.#fontController.add(families);
355605
+ }
355606
+ async preloadFonts(families) {
355607
+ await this.#fontController.preload(families);
355608
+ }
355609
+ #requestFontReflow() {
355610
+ this.#layoutState = {
355611
+ ...this.#layoutState,
355612
+ blocks: [],
355613
+ measures: [],
355614
+ layout: null
355615
+ };
355616
+ this.#pendingDocChange = true;
355617
+ this.#scheduleRerender();
355210
355618
  }
355211
355619
  #emitFontsChangedIfChanged(summary) {
355212
355620
  const gate = this.#fontGate;
355213
355621
  if (!gate)
355214
355622
  return;
355215
355623
  const version$1 = gate.fontConfigVersion;
355216
- const key2 = `${version$1}|${summary ? summary.results.map((result) => `${result.family}:${result.status}`).sort().join(",") : ""}`;
355624
+ const statusKey = summary ? summary.results.map((result) => `${result.family}:${result.status}`).sort().join(",") : "";
355625
+ const key2 = `${version$1}|${this.#fontPlan?.effectiveSignature ?? ""}|${statusKey}`;
355217
355626
  if (key2 === this.#lastFontsChangedKey)
355218
355627
  return;
355219
355628
  const isInitial = this.#lastFontsChangedKey === null;
355629
+ const epochBumped = !isInitial && version$1 !== this.#lastFontsChangedVersion;
355220
355630
  this.#lastFontsChangedKey = key2;
355631
+ this.#lastFontsChangedVersion = version$1;
355632
+ const pendingSource = this.#nextFontsChangedSource;
355633
+ this.#nextFontsChangedSource = null;
355634
+ const source = isInitial ? "initial" : pendingSource ?? (epochBumped ? "late-load" : "render-change");
355221
355635
  let resolutions;
355222
355636
  try {
355223
355637
  resolutions = gate.getReport();
@@ -355225,9 +355639,9 @@ function print() { __p += __j.call(arguments, '') }
355225
355639
  return;
355226
355640
  }
355227
355641
  const payload = {
355228
- documentFonts: resolutions.map((record) => record.logicalFamily),
355642
+ documentFonts: [...new Set(resolutions.map((record) => record.logicalFamily))],
355229
355643
  resolutions,
355230
- missingFonts: resolutions.filter((record) => record.missing).map((record) => record.logicalFamily),
355644
+ missingFonts: [...new Set(resolutions.filter((record) => record.missing).map((record) => record.logicalFamily))],
355231
355645
  loadSummary: summary ?? {
355232
355646
  loaded: 0,
355233
355647
  failed: 0,
@@ -355235,7 +355649,7 @@ function print() { __p += __j.call(arguments, '') }
355235
355649
  fallbackUsed: 0,
355236
355650
  results: []
355237
355651
  },
355238
- source: isInitial ? "initial" : "late-load",
355652
+ source,
355239
355653
  version: version$1
355240
355654
  };
355241
355655
  this.#lastFontsChangedPayload = payload;
@@ -355246,6 +355660,14 @@ function print() { __p += __j.call(arguments, '') }
355246
355660
  getLastFontsChangedPayload() {
355247
355661
  return this.#lastFontsChangedPayload;
355248
355662
  }
355663
+ #resetFontReportStateForDocumentChange() {
355664
+ this.#nextFontsChangedSource = null;
355665
+ this.#lastFontsChangedKey = null;
355666
+ this.#lastFontsChangedVersion = -1;
355667
+ this.#lastFontsChangedPayload = null;
355668
+ this.#fontPlan = null;
355669
+ this.#fontPlanBlocks = null;
355670
+ }
355249
355671
  getLayoutOptions() {
355250
355672
  return { ...this.#layoutOptions };
355251
355673
  }
@@ -355394,7 +355816,7 @@ function print() { __p += __j.call(arguments, '') }
355394
355816
  flowMode: this.#layoutOptions.flowMode ?? "paginated",
355395
355817
  blocks: blocks2,
355396
355818
  measures,
355397
- fontSignature: this.#fontResolver.signature
355819
+ fontSignature: this.#layoutFontSignature
355398
355820
  });
355399
355821
  const isSemanticFlow = this.#layoutOptions.flowMode === "semantic";
355400
355822
  this.#ensurePainter();
@@ -356114,6 +356536,7 @@ function print() { __p += __j.call(arguments, '') }
356114
356536
  this.#postPaintPipeline.destroy();
356115
356537
  this.#proofingManager?.dispose();
356116
356538
  this.#proofingManager = null;
356539
+ this.#fontController.dispose();
356117
356540
  this.#fontGate?.dispose();
356118
356541
  this.#fontGate = null;
356119
356542
  if (this.#cursorUpdateTimer !== null) {
@@ -356474,7 +356897,10 @@ function print() { __p += __j.call(arguments, '') }
356474
356897
  });
356475
356898
  const handleDocumentReplaced = () => {
356476
356899
  this.#fontGate?.resetForDocumentChange();
356477
- this.#fontResolver.reset();
356900
+ this.#fontController.reset();
356901
+ this.#layoutFontSignature = "";
356902
+ this.#fontController.applyInitialConfig(this.#options.fontAssets);
356903
+ this.#resetFontReportStateForDocumentChange();
356478
356904
  this.#refreshHeaderFooterStructureThenRerender({ purgeCachedEditors: true });
356479
356905
  };
356480
356906
  this.#editor.on("documentReplaced", handleDocumentReplaced);
@@ -357599,9 +358025,13 @@ function print() { __p += __j.call(arguments, '') }
357599
358025
  const previousBlocks = this.#layoutState.blocks;
357600
358026
  const previousLayout = this.#layoutState.layout;
357601
358027
  const previousMeasures = this.#layoutState.measures;
357602
- const resolvePhysical = (css) => this.#fontResolver.resolvePhysicalFamily(css);
357603
- const fontSignature = this.#fontResolver.signature;
358028
+ const resolvePhysical = (css, face) => this.#fontResolver.resolvePhysicalFamilyForFace(css, face, this.#hasFace);
358029
+ let fontSignature = "";
357604
358030
  const previousFontSignature = this.#layoutFontSignature;
358031
+ let fontMeasureContext = {
358032
+ resolvePhysical,
358033
+ fontSignature
358034
+ };
357605
358035
  let layout;
357606
358036
  let measures;
357607
358037
  let resolvedLayout;
@@ -357620,13 +358050,19 @@ function print() { __p += __j.call(arguments, '') }
357620
358050
  ...headerFooterInput ? this.#collectHeaderFooterFaceBlocks(headerFooterInput) : [],
357621
358051
  ...!isSemanticFlow && footnotesLayoutInput?.blocksById ? [...footnotesLayoutInput.blocksById.values()].flat() : []
357622
358052
  ];
358053
+ this.#fontPlan = planFontFaces(this.#fontPlanBlocks, this.#fontResolver, this.#hasFace);
358054
+ fontSignature = this.#fontPlan.effectiveSignature;
358055
+ fontMeasureContext = {
358056
+ resolvePhysical,
358057
+ fontSignature
358058
+ };
357623
358059
  const fontSummary = await this.#fontGate?.ensureReadyForMeasure() ?? null;
357624
358060
  this.#emitFontsChangedIfChanged(fontSummary);
357625
358061
  } catch {}
357626
358062
  try {
357627
358063
  const incrementalLayoutStart = perfNow();
357628
- const result = await incrementalLayout(previousBlocks, previousLayout, blocksForLayout, layoutOptions, (block, constraints) => measureBlock(block, constraints, resolvePhysical), headerFooterInput ?? undefined, previousMeasures, {
357629
- fontSignature,
358064
+ const result = await incrementalLayout(previousBlocks, previousLayout, blocksForLayout, layoutOptions, (block, constraints) => measureBlock(block, constraints, fontMeasureContext), headerFooterInput ?? undefined, previousMeasures, {
358065
+ fontContext: fontMeasureContext,
357630
358066
  previousFontSignature
357631
358067
  });
357632
358068
  perfLog(`[Perf] incrementalLayout: ${(perfNow() - incrementalLayoutStart).toFixed(2)}ms`);
@@ -357779,7 +358215,7 @@ function print() { __p += __j.call(arguments, '') }
357779
358215
  pageGap: this.#layoutState.layout?.pageGap ?? effectiveGap,
357780
358216
  showFormattingMarks: this.#layoutOptions.showFormattingMarks ?? false,
357781
358217
  contentControlsChrome: this.#layoutOptions.contentControlsChrome ?? "default",
357782
- resolvePhysical: (css) => this.#fontResolver.resolvePhysicalFamily(css)
358218
+ resolvePhysical: (css, face) => this.#fontResolver.resolvePhysicalFamilyForFace(css, face, this.#hasFace)
357783
358219
  });
357784
358220
  const currentZoom = this.#layoutOptions.zoom ?? 1;
357785
358221
  if (currentZoom !== 1)
@@ -358531,7 +358967,7 @@ function print() { __p += __j.call(arguments, '') }
358531
358967
  }
358532
358968
  async#layoutPerRIdHeaderFooters(headerFooterInput, layout, sectionMetadata) {
358533
358969
  if (this.#headerFooterSession)
358534
- await this.#headerFooterSession.layoutPerRId(headerFooterInput, layout, sectionMetadata, this.#fontResolver);
358970
+ await this.#headerFooterSession.layoutPerRId(headerFooterInput, layout, sectionMetadata, this.#fontResolver, this.#hasFace, this.#fontPlan?.effectiveSignature ?? "");
358535
358971
  }
358536
358972
  #updateDecorationProviders(resolvedLayout) {
358537
358973
  this.#headerFooterSession?.updateDecorationProviders(resolvedLayout);
@@ -360478,7 +360914,7 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
360478
360914
 
360479
360915
  // ../../packages/superdoc/dist/super-editor.es.js
360480
360916
  var init_super_editor_es = __esm(() => {
360481
- init_src_CF4og_LY_es();
360917
+ init_src_DvgAvHbj_es();
360482
360918
  init_SuperConverter_B9mZiCO9_es();
360483
360919
  init_jszip_C49i9kUs_es();
360484
360920
  init_xml_js_CqGKpaft_es();