@shbernal/ts-pptx 4.0.1 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -114
- package/dist/anim-presets-Qbgh8uut.js +55 -0
- package/dist/anim-presets-Qbgh8uut.js.map +1 -0
- package/dist/{autopage-odPz7zZO.js → autopage-DqZ37VpL.js} +11 -12
- package/dist/autopage-DqZ37VpL.js.map +1 -0
- package/dist/{binary-string-CKVAYI3M.js → binary-string-Ba8VM3b9.js} +3 -4
- package/dist/binary-string-Ba8VM3b9.js.map +1 -0
- package/dist/{body-insets-Dw_BeWD_.js → body-insets-BDHymJvz.js} +7 -9
- package/dist/body-insets-BDHymJvz.js.map +1 -0
- package/dist/browser.d.ts +24 -16
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +19 -19
- package/dist/browser.js.map +1 -1
- package/dist/{image-size-CvN2iCA4.js → chart-metadata-CwiTTcJq.js} +634 -537
- package/dist/chart-metadata-CwiTTcJq.js.map +1 -0
- package/dist/{clip-Bl01BPcN.d.ts → clip-ISfCMtWA.d.ts} +6 -10
- package/dist/clip-ISfCMtWA.d.ts.map +1 -0
- package/dist/{notes-Dh12JAbn.js → comments-CKIZYRbZ.js} +530 -401
- package/dist/comments-CKIZYRbZ.js.map +1 -0
- package/dist/{diagnostics-D8ot4Ei7.d.ts → diagnostics-MoA4MBq5.d.ts} +55 -53
- package/dist/diagnostics-MoA4MBq5.d.ts.map +1 -0
- package/dist/{embedded-fonts-DarT9aoa.d.ts → embedded-fonts-U7HIIhPO.d.ts} +4 -6
- package/dist/embedded-fonts-U7HIIhPO.d.ts.map +1 -0
- package/dist/{entry-compose-DCnvBZz2.d.ts → entry-compose-CiakSt-f.d.ts} +62 -81
- package/dist/entry-compose-CiakSt-f.d.ts.map +1 -0
- package/dist/{errors-C4oENPcu.js → entry-errors-JMthgJ2g.js} +45 -29
- package/dist/entry-errors-JMthgJ2g.js.map +1 -0
- package/dist/{table-cell-margins-EVg0EwxT.js → enums-BP9wsb9Q.js} +44 -47
- package/dist/enums-BP9wsb9Q.js.map +1 -0
- package/dist/{enums-BUKTUB6V.d.ts → enums-PcXr3o3J.d.ts} +13 -14
- package/dist/{enums-BUKTUB6V.d.ts.map → enums-PcXr3o3J.d.ts.map} +1 -1
- package/dist/families.d.ts +24 -26
- package/dist/families.d.ts.map +1 -1
- package/dist/families.js +3 -4
- package/dist/{fit-Cb7naFj6.js → fit-Bpmzep6O.js} +64 -56
- package/dist/fit-Bpmzep6O.js.map +1 -0
- package/dist/{font-metrics-v5fn7s7e.d.ts → font-metrics-DTppw4t3.d.ts} +62 -38
- package/dist/font-metrics-DTppw4t3.d.ts.map +1 -0
- package/dist/{grid-DikTjFey.js → grid-DUIMxjfl.js} +23 -26
- package/dist/grid-DUIMxjfl.js.map +1 -0
- package/dist/{html-dom-Iuog2wdK.js → html-dom-LZCgntnJ.js} +46 -47
- package/dist/html-dom-LZCgntnJ.js.map +1 -0
- package/dist/html.d.ts +53 -9
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +12 -13
- package/dist/html.js.map +1 -1
- package/dist/index.d.ts +21 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +16 -18
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +18 -19
- package/dist/inspect.js.map +1 -1
- package/dist/{text-anchor-CrYXAfUu.js → lock-attrs-CSQnFDHP.js} +62 -12
- package/dist/lock-attrs-CSQnFDHP.js.map +1 -0
- package/dist/math.d.ts +2 -4
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +12 -13
- package/dist/math.js.map +1 -1
- package/dist/measure.d.ts +23 -12
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +3 -3
- package/dist/node.d.ts +21 -13
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +12 -12
- package/dist/node.js.map +1 -1
- package/dist/{options-internal-WqgMf720.js → options-internal-BWgmLPdx.js} +4 -5
- package/dist/options-internal-BWgmLPdx.js.map +1 -0
- package/dist/{package-J49Ck6S2.d.ts → package-CANBWuSm.d.ts} +9 -13
- package/dist/package-CANBWuSm.d.ts.map +1 -0
- package/dist/{playbtn-CUqQdoDf.js → playbtn-BQZFJir9.js} +4 -5
- package/dist/playbtn-BQZFJir9.js.map +1 -0
- package/dist/{pres-C6qgOFAa.d.ts → pres-BkEkUAEM.d.ts} +410 -237
- package/dist/pres-BkEkUAEM.d.ts.map +1 -0
- package/dist/{presentation-DGYlAWhl.js → presentation-4Ggq0_Xa.js} +470 -315
- package/dist/presentation-4Ggq0_Xa.js.map +1 -0
- package/dist/{presentation-types-8jLQHI4M.d.ts → presentation-types-BgnZR-0a.d.ts} +1119 -468
- package/dist/presentation-types-BgnZR-0a.d.ts.map +1 -0
- package/dist/read.d.ts +18 -13
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +4 -4
- package/dist/script.d.ts +116 -65
- package/dist/script.d.ts.map +1 -1
- package/dist/script.js +2700 -780
- package/dist/script.js.map +1 -1
- package/dist/{shapes-re0KyQk_.js → shapes-CAPOjU0Q.js} +1564 -491
- package/dist/shapes-CAPOjU0Q.js.map +1 -0
- package/dist/{slide-Dx2ZeVZ6.d.ts → slide-BmT4kMoO.d.ts} +102 -89
- package/dist/slide-BmT4kMoO.d.ts.map +1 -0
- package/dist/{slide-size-BalTjFuv.js → slide-size-SkScz1ig.js} +2 -3
- package/dist/{slide-size-BalTjFuv.js.map → slide-size-SkScz1ig.js.map} +1 -1
- package/dist/{table-dom-BTDP3lEP.js → table-dom-BYga4FYY.js} +4 -5
- package/dist/{table-dom-BTDP3lEP.js.map → table-dom-BYga4FYY.js.map} +1 -1
- package/dist/{text-sN64Otf_.js → text-CU08xJGs.js} +393 -344
- package/dist/text-CU08xJGs.js.map +1 -0
- package/dist/{transition-speed-kUEWDWTx.js → transition-speed-CNJ0fSpQ.js} +2 -3
- package/dist/{transition-speed-kUEWDWTx.js.map → transition-speed-CNJ0fSpQ.js.map} +1 -1
- package/dist/{units-internal-XJlf-hOl.js → units-internal-BR3a4cIi.js} +34 -32
- package/dist/units-internal-BR3a4cIi.js.map +1 -0
- package/dist/{zip-CKd8ihcf.js → zip-7JTh61LX.js} +8 -10
- package/dist/zip-7JTh61LX.js.map +1 -0
- package/dist/{zip-C0leZZMj.d.ts → zip-uUjs9Cqx.d.ts} +4 -6
- package/dist/zip-uUjs9Cqx.d.ts.map +1 -0
- package/dist/zip.d.ts +3 -3
- package/dist/zip.js +3 -3
- package/dist/{zoom-DPUHh85d.js → zoom-CSSeOwM8.js} +1204 -620
- package/dist/zoom-CSSeOwM8.js.map +1 -0
- package/package.json +27 -28
- package/skills/{ts-pptx-upstream → pptx-ts-upstream}/SKILL.md +37 -84
- package/dist/autopage-odPz7zZO.js.map +0 -1
- package/dist/binary-string-CKVAYI3M.js.map +0 -1
- package/dist/body-insets-Dw_BeWD_.js.map +0 -1
- package/dist/clip-Bl01BPcN.d.ts.map +0 -1
- package/dist/diagnostics-D8ot4Ei7.d.ts.map +0 -1
- package/dist/embedded-fonts-DarT9aoa.d.ts.map +0 -1
- package/dist/entry-compose-DCnvBZz2.d.ts.map +0 -1
- package/dist/errors-C4oENPcu.js.map +0 -1
- package/dist/fit-Cb7naFj6.js.map +0 -1
- package/dist/font-metrics-v5fn7s7e.d.ts.map +0 -1
- package/dist/grid-DikTjFey.js.map +0 -1
- package/dist/html-dom-Iuog2wdK.js.map +0 -1
- package/dist/image-size-CvN2iCA4.js.map +0 -1
- package/dist/notes-Dh12JAbn.js.map +0 -1
- package/dist/options-internal-WqgMf720.js.map +0 -1
- package/dist/package-J49Ck6S2.d.ts.map +0 -1
- package/dist/playbtn-CUqQdoDf.js.map +0 -1
- package/dist/pres-C6qgOFAa.d.ts.map +0 -1
- package/dist/presentation-DGYlAWhl.js.map +0 -1
- package/dist/presentation-types-8jLQHI4M.d.ts.map +0 -1
- package/dist/shapes-re0KyQk_.js.map +0 -1
- package/dist/slide-Dx2ZeVZ6.d.ts.map +0 -1
- package/dist/table-cell-margins-EVg0EwxT.js.map +0 -1
- package/dist/text-anchor-CrYXAfUu.js.map +0 -1
- package/dist/text-sN64Otf_.js.map +0 -1
- package/dist/units-internal-XJlf-hOl.js.map +0 -1
- package/dist/zip-C0leZZMj.d.ts.map +0 -1
- package/dist/zip-CKd8ihcf.js.map +0 -1
- package/dist/zoom-DPUHh85d.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as resolveCellMarginsInches, b as resolveTableColWidthsEmu, d as marginToEmu, s as getSmartParseNumber, t as autoPageLineHeightEmu, v as resolveInsetsEmu, x as resolveTableRowHeightEmu } from "./units-internal-
|
|
3
|
-
import {
|
|
4
|
-
import { t as
|
|
5
|
-
import { t as
|
|
6
|
-
import { n as tableColCount, r as walkTableGrid } from "./grid-
|
|
7
|
-
|
|
1
|
+
import { D as emuToInches, I as EMU_PER_POINT } from "./enums-BP9wsb9Q.js";
|
|
2
|
+
import { _ as resolveCellMarginsInches, b as resolveTableColWidthsEmu, d as marginToEmu, s as getSmartParseNumber, t as autoPageLineHeightEmu, v as resolveInsetsEmu, x as resolveTableRowHeightEmu } from "./units-internal-BR3a4cIi.js";
|
|
3
|
+
import { i as MediaError, r as InvalidOptionError, s as UnsupportedFeatureError, u as warn } from "./entry-errors-JMthgJ2g.js";
|
|
4
|
+
import { t as BODY_INSET_DEFAULTS_EMU } from "./body-insets-BDHymJvz.js";
|
|
5
|
+
import { t as pickDefined } from "./options-internal-BWgmLPdx.js";
|
|
6
|
+
import { n as tableColCount, r as walkTableGrid } from "./grid-DUIMxjfl.js";
|
|
7
|
+
// src/measure/font-collection.ts
|
|
8
8
|
/**
|
|
9
9
|
* Font **collection** (`.ttc` / `.otc`) support for the write-side metrics.
|
|
10
10
|
*
|
|
@@ -262,8 +262,7 @@ function extractFontFace(data, index) {
|
|
|
262
262
|
}
|
|
263
263
|
return out;
|
|
264
264
|
}
|
|
265
|
-
|
|
266
|
-
//#region src/measure/font-metrics.ts
|
|
265
|
+
// src/measure/font-metrics.ts
|
|
267
266
|
/**
|
|
268
267
|
* Write-side font metrics.
|
|
269
268
|
*
|
|
@@ -274,7 +273,7 @@ function extractFontFace(data, index) {
|
|
|
274
273
|
*
|
|
275
274
|
* Width is summed from **raw `hmtx` advances with no kerning/shaping** (GPOS/GSUB
|
|
276
275
|
* are deliberately ignored): kerning almost always narrows a line, so raw advances
|
|
277
|
-
* over-estimate width
|
|
276
|
+
* over-estimate width, the conservative direction (shrink a touch too much, never
|
|
278
277
|
* overflow). See `docs/contributing/design/text-fit.md` ("Font metrics provider").
|
|
279
278
|
*/
|
|
280
279
|
var OpentypeFontMetrics = class {
|
|
@@ -345,7 +344,7 @@ let heuristicSingleton;
|
|
|
345
344
|
/**
|
|
346
345
|
* Shared, font-independent `FontMetrics` used when a named face has no registered
|
|
347
346
|
* metrics but the deck has opted into measured fit (some other face is registered).
|
|
348
|
-
* Approximate but conservative
|
|
347
|
+
* Approximate but conservative; see `heuristicCharRatio`. A deck with no
|
|
349
348
|
* registered metrics at all does not engage measured fit, so this never fires there.
|
|
350
349
|
*/
|
|
351
350
|
function getHeuristicFontMetrics() {
|
|
@@ -402,7 +401,7 @@ var FontMetricsRegistry = class {
|
|
|
402
401
|
* Coverage of code point `cp` for `face`, read from the registered font's cmap:
|
|
403
402
|
* `true`/`false` when a variant of `face` is registered (see {@link get} for the
|
|
404
403
|
* exact→regular→any-variant fallback), or `undefined` when the face has **no**
|
|
405
|
-
* registered metrics
|
|
404
|
+
* registered metrics: "unknown", deliberately distinct from a `false`
|
|
406
405
|
* "registered but not covered". A coverage audit must not treat an unregistered
|
|
407
406
|
* face as fully covered, so callers get `undefined` here rather than the per-face
|
|
408
407
|
* {@link FontMetrics.hasCodepoint} boolean (which, for the heuristic fallback,
|
|
@@ -477,8 +476,7 @@ function collectUncoveredCodepoints(paragraphs, registry, into) {
|
|
|
477
476
|
if (missing) into.set(face, missing);
|
|
478
477
|
}
|
|
479
478
|
}
|
|
480
|
-
|
|
481
|
-
//#region src/measure/text-fit.ts
|
|
479
|
+
// src/measure/text-fit.ts
|
|
482
480
|
/**
|
|
483
481
|
* PowerPoint single-spacing line pitch as a multiple of font size.
|
|
484
482
|
*
|
|
@@ -497,10 +495,10 @@ const MIN_FONT_SCALE_PCT = 25;
|
|
|
497
495
|
* Conservative safety factors applied by the shrink solver (not by the pure
|
|
498
496
|
* `measureHeightPt`). Raw `hmtx` advances summed without shaping still pack a line
|
|
499
497
|
* a little tighter than PowerPoint, which lays text out at a device DPI and rounds
|
|
500
|
-
* each glyph advance up
|
|
498
|
+
* each glyph advance up, so PowerPoint wraps marginally earlier and its fitted
|
|
501
499
|
* box is marginally taller. Inflating measured width and height by these factors
|
|
502
500
|
* makes the computed `fontScale` ≤ PowerPoint's across the calibration oracle
|
|
503
|
-
* (`test/read/autofit-calibration-oracle.test.
|
|
501
|
+
* (`test/read/autofit-calibration-oracle.test.ts`: 0 violations over the Aptos
|
|
504
502
|
* cases). They err on the side of shrinking slightly too much, never overflowing.
|
|
505
503
|
*/
|
|
506
504
|
const WIDTH_SAFETY_FACTOR = 1.03;
|
|
@@ -515,7 +513,7 @@ const isWhitespace = (ch) => ch === " " || ch === " " || ch === "\xA0" || /\s/.t
|
|
|
515
513
|
*
|
|
516
514
|
* **Hangul is deliberately absent.** UAX #14 makes Hangul breakable between
|
|
517
515
|
* syllables, but PowerPoint does not: Korean is written with spaces between words
|
|
518
|
-
* and the app breaks it like Latin. `autofit-cjk-wrap.pptx` pins that directly
|
|
516
|
+
* and the app breaks it like Latin. `autofit-cjk-wrap.pptx` pins that directly:
|
|
519
517
|
* the same box that lays out in 2 lines in Han or Kana takes 3 in Hangul, because
|
|
520
518
|
* the run moves down whole. A Hangul run longer than one line still breaks between
|
|
521
519
|
* syllables, but that is the over-long-token character-wrap fallback in
|
|
@@ -540,7 +538,7 @@ function isCjkBreakCharacter(ch) {
|
|
|
540
538
|
/**
|
|
541
539
|
* Tokenize one paragraph at a given `fontScalePct`. Words can span run boundaries
|
|
542
540
|
* (a break is only allowed at whitespace, or either side of a per-character
|
|
543
|
-
* breaking code point
|
|
541
|
+
* breaking code point; see `isCjkBreakCharacter`). Returns `null` if any run's
|
|
544
542
|
* face has no registered metrics (the paragraph cannot be measured).
|
|
545
543
|
*/
|
|
546
544
|
function tokenizeParagraph(para, resolve, fontScalePct, widthSafety) {
|
|
@@ -598,7 +596,7 @@ function tokenizeParagraph(para, resolve, fontScalePct, widthSafety) {
|
|
|
598
596
|
* laid-out line width. `maxLineWidthPt` tracks the running line width and records
|
|
599
597
|
* it whenever a line completes (a wrap or the final line), so callers can measure
|
|
600
598
|
* the actual text extent, not just the box width. Trailing whitespace counts
|
|
601
|
-
* toward width, as PowerPoint counts it, which slightly over-reports
|
|
599
|
+
* toward width, as PowerPoint counts it, which slightly over-reports: the
|
|
602
600
|
* conservative direction, consistent with the wrap model erring wide. The
|
|
603
601
|
* PowerPoint behaviour this follows is tabled in `docs/contributing/design/text-fit.md`.
|
|
604
602
|
*/
|
|
@@ -690,16 +688,16 @@ function measureHeightPt(paragraphs, innerWidthPt, resolve, fontScalePct, lnSpcR
|
|
|
690
688
|
* Width used for wrap layout: the inner box width when wrapping, or unbounded for a
|
|
691
689
|
* non-wrapping frame (`wrap:false`) so each paragraph lays out as a single line. A
|
|
692
690
|
* non-wrapping frame's width constraint is enforced separately, against the widest
|
|
693
|
-
* laid-out line
|
|
691
|
+
* laid-out line (see {@link solveShrink}).
|
|
694
692
|
*/
|
|
695
693
|
function layoutWidthPt(box) {
|
|
696
694
|
return box.wrap === false ? Infinity : box.innerWidthPt;
|
|
697
695
|
}
|
|
698
696
|
/**
|
|
699
|
-
* Inner height (points) the text needs at full size
|
|
697
|
+
* Inner height (points) the text needs at full size: the value to bake into the
|
|
700
698
|
* shape's `a:ext/@cy` for `fit: 'resize'` (`spAutoFit`). Unlike shrink, resize has
|
|
701
699
|
* **no safety net**: an under-estimate overflows (there is no text scaling
|
|
702
|
-
* fallback), so this errs **tall
|
|
700
|
+
* fallback), so this errs **tall**. Width is inflated (earlier wrap ⇒ more lines)
|
|
703
701
|
* and the laid-out height by the calibrated height factor, so the computed `cy` is
|
|
704
702
|
* ≥ PowerPoint's and ≥ the LibreOffice-rendered height across the resize oracle.
|
|
705
703
|
*/
|
|
@@ -716,7 +714,7 @@ function solveResize(paragraphs, box, resolve) {
|
|
|
716
714
|
* Width and height both re-measured per scale. Conservative: because the model
|
|
717
715
|
* over-estimates, the returned scale is ≤ PowerPoint's and the text never overflows.
|
|
718
716
|
*
|
|
719
|
-
* `lnSpcReduction` is left at 0
|
|
717
|
+
* `lnSpcReduction` is left at 0: dropping `fontScale` alone is provably
|
|
720
718
|
* conservative (PowerPoint trades line-spacing reduction to keep the font *larger*,
|
|
721
719
|
* so a reduction-free fit is always ≤ PowerPoint's scale). The reduction ramp
|
|
722
720
|
* PowerPoint applies is recorded in `docs/contributing/design/text-fit.md`.
|
|
@@ -749,10 +747,9 @@ function solveShrink(paragraphs, box, resolve) {
|
|
|
749
747
|
}
|
|
750
748
|
};
|
|
751
749
|
}
|
|
752
|
-
|
|
753
|
-
//#region src/measure/paragraphs.ts
|
|
750
|
+
// src/measure/paragraphs.ts
|
|
754
751
|
/**
|
|
755
|
-
* ts
|
|
752
|
+
* pptx-ts: turning a slide text object into the simulator's inputs
|
|
756
753
|
*
|
|
757
754
|
* The lower half of the measured-fit pass: normalize a text object's runs into `FitParagraph`s,
|
|
758
755
|
* resolve its body insets and box, and work out how a height change is shared between `off.y` and
|
|
@@ -785,9 +782,7 @@ function normalizeRuns(obj) {
|
|
|
785
782
|
/** Build a measurable `FitParagraph[]` from a text object, or null if not measurable. */
|
|
786
783
|
function extractParagraphs(obj) {
|
|
787
784
|
const opts = obj.options ?? {};
|
|
788
|
-
|
|
789
|
-
if (runs.length === 0) return null;
|
|
790
|
-
return buildFitParagraphs(runs, opts);
|
|
785
|
+
return buildFitParagraphs(normalizeRuns(obj), opts);
|
|
791
786
|
}
|
|
792
787
|
/**
|
|
793
788
|
* Convert a run list (+ box-level default options) into a measurable
|
|
@@ -888,7 +883,7 @@ function resolveBodyInsetsEmu(opts) {
|
|
|
888
883
|
/**
|
|
889
884
|
* Resolve the inner box (shape minus insets) in points; null if degenerate.
|
|
890
885
|
*
|
|
891
|
-
* Reads the object's own `opts.w/h` with no ancestor walk
|
|
886
|
+
* Reads the object's own `opts.w/h` with no ancestor walk. That is correct only because a group keeps an
|
|
892
887
|
* identity child coordinate space (`chOff/chExt == off/ext`, see the `gen/slide/object.ts` group renderer and
|
|
893
888
|
* `docs/groups.md`), so a group never scales its children and a grouped text box's authored w/h is its
|
|
894
889
|
* true rendered size. `applyMeasuredFit` reaches here for grouped text via its explicit group descent
|
|
@@ -919,10 +914,9 @@ function anchorTopShareOfDelta(opts) {
|
|
|
919
914
|
if (anchor === "b") return 1;
|
|
920
915
|
return .5;
|
|
921
916
|
}
|
|
922
|
-
|
|
923
|
-
//#region src/gen/table/cell-inherit.ts
|
|
917
|
+
// src/gen/table/cell-inherit.ts
|
|
924
918
|
/**
|
|
925
|
-
* ts
|
|
919
|
+
* pptx-ts: what a table cell inherits from its table.
|
|
926
920
|
*
|
|
927
921
|
* A cell that states nothing takes the table's value, and two paths resolve that: the emitter,
|
|
928
922
|
* building the bag it hands to the text-body writer, and the measured-fit pass, building the
|
|
@@ -948,6 +942,7 @@ function anchorTopShareOfDelta(opts) {
|
|
|
948
942
|
const CELL_INHERITED_TEXT_KEYS = [
|
|
949
943
|
"align",
|
|
950
944
|
"bold",
|
|
945
|
+
"breakLine",
|
|
951
946
|
"charSpacing",
|
|
952
947
|
"fontFace",
|
|
953
948
|
"fontSize",
|
|
@@ -957,25 +952,40 @@ const CELL_INHERITED_TEXT_KEYS = [
|
|
|
957
952
|
"margin",
|
|
958
953
|
"valign"
|
|
959
954
|
];
|
|
960
|
-
/**
|
|
955
|
+
/**
|
|
956
|
+
* The keys only the emitter inherits: they paint, or the fitter does not model them.
|
|
957
|
+
*
|
|
958
|
+
* `TableProps` takes every `TextBaseProps` key, and each of these writes on a cell. Eleven of them
|
|
959
|
+
* used to be missing from both lists, so a table-level `highlight` or `bullet` was accepted and
|
|
960
|
+
* wrote nothing, with no warning (#227).
|
|
961
|
+
*/
|
|
961
962
|
const CELL_INHERITED_EMIT_KEYS = [
|
|
962
963
|
"border",
|
|
964
|
+
"bullet",
|
|
965
|
+
"caps",
|
|
963
966
|
"color",
|
|
964
967
|
"fill",
|
|
968
|
+
"fontFaceEA",
|
|
969
|
+
"highlight",
|
|
970
|
+
"lang",
|
|
971
|
+
"paraIndent",
|
|
972
|
+
"paraMarginLeft",
|
|
973
|
+
"softBreakBefore",
|
|
974
|
+
"tabStops",
|
|
965
975
|
"textDirection",
|
|
976
|
+
"transparency",
|
|
966
977
|
"underline"
|
|
967
978
|
];
|
|
968
979
|
/** Every key the emitter inherits from the table onto a cell. */
|
|
969
980
|
const CELL_INHERITED_KEYS = [...CELL_INHERITED_TEXT_KEYS, ...CELL_INHERITED_EMIT_KEYS];
|
|
970
|
-
|
|
971
|
-
//#region src/measure/table-fit.ts
|
|
981
|
+
// src/measure/table-fit.ts
|
|
972
982
|
/**
|
|
973
|
-
* ts
|
|
983
|
+
* pptx-ts: measuring a table's row heights and cell fits
|
|
974
984
|
*
|
|
975
985
|
* A table is measured cell by cell against its resolved grid: each cell inherits the table's text
|
|
976
986
|
* options where it sets none, gets its own margins resolved to EMU insets, and is laid out inside
|
|
977
987
|
* the column span it actually occupies. A merged region is measured once, at its origin, across
|
|
978
|
-
* the columns it covers
|
|
988
|
+
* the columns it covers, which is what `walkTableGrid` exists to hand out.
|
|
979
989
|
*/
|
|
980
990
|
/**
|
|
981
991
|
* Effective cell options: the cell's own values, with table-level values filled in where unset.
|
|
@@ -984,7 +994,7 @@ const CELL_INHERITED_KEYS = [...CELL_INHERITED_TEXT_KEYS, ...CELL_INHERITED_EMIT
|
|
|
984
994
|
* emitter's list that decides how text lays out. This used to be its own list, claiming in its
|
|
985
995
|
* docstring to mirror the emitter's while naming four keys the emitter did not.
|
|
986
996
|
*
|
|
987
|
-
* PowerPoint has no text-autofit for a table cell
|
|
997
|
+
* PowerPoint has no text-autofit for a table cell: `a:tcPr` carries no autofit, and the app
|
|
988
998
|
* ignores a `normAutofit` inside one; rows auto-grow instead. So a cell's `fit: 'shrink'` is
|
|
989
999
|
* honoured by baking a *reduced literal font size* onto its runs, which both PowerPoint and
|
|
990
1000
|
* LibreOffice render identically with no edit or resize. That is what makes these options worth
|
|
@@ -1034,7 +1044,7 @@ function scaleCellFontSizes(cell, eff, f) {
|
|
|
1034
1044
|
* Resolve a table's grid the one way every consumer has to see it.
|
|
1035
1045
|
*
|
|
1036
1046
|
* Three sites derived these four things: `pptx.tableLayout()`, the export-time measured-fit
|
|
1037
|
-
* pass, and the table emitter (the height alone). They already disagreed
|
|
1047
|
+
* pass, and the table emitter (the height alone). They already disagreed: only the fit pass
|
|
1038
1048
|
* read `cy`, the EMU height the auto-pager and the fit pass itself stamp onto the options, so
|
|
1039
1049
|
* `addTable(rows, { cy })` with no `h` gave a file whose rows are pinned and a
|
|
1040
1050
|
* `pptx.tableLayout()` that reported every row auto-height. That is the same drift the one
|
|
@@ -1059,12 +1069,12 @@ function resolveTableGridEmu(rows, opts, presLayout) {
|
|
|
1059
1069
|
};
|
|
1060
1070
|
}
|
|
1061
1071
|
/**
|
|
1062
|
-
* Compute per-cell geometry (inches) for a table laid out at `opts.x`/`y`/`w
|
|
1063
|
-
* engine behind `pptx.tableLayout()`. Column widths come from the same
|
|
1072
|
+
* Compute per-cell geometry (inches) for a table laid out at `opts.x`/`y`/`w`. This is
|
|
1073
|
+
* the engine behind `pptx.tableLayout()`. Column widths come from the same
|
|
1064
1074
|
* {@link resolveTableColWidthsEmu} the writer uses, so cell x/width are exact. Row
|
|
1065
1075
|
* heights are exact when pinned by `rowH` (array or scalar) or table `h`; otherwise
|
|
1066
1076
|
* each auto-height row is estimated with the same conservative (tall) text model as
|
|
1067
|
-
* {@link measureText} and flagged `heightExact: false`. Single-slide only
|
|
1077
|
+
* {@link measureText} and flagged `heightExact: false`. Single-slide only:
|
|
1068
1078
|
* `autoPage` paging across slides is not modeled. Rowspan cells do not drive a row's
|
|
1069
1079
|
* estimated height (mirrors `gen/table/autopage.ts`, which exempts them from line-height growth).
|
|
1070
1080
|
*/
|
|
@@ -1158,8 +1168,7 @@ function computeTableLayout(rows, opts, presLayout, registry) {
|
|
|
1158
1168
|
heightExact: rowExact.every(Boolean)
|
|
1159
1169
|
};
|
|
1160
1170
|
}
|
|
1161
|
-
|
|
1162
|
-
//#region src/measure/fit.ts
|
|
1171
|
+
// src/measure/fit.ts
|
|
1163
1172
|
/** Map the public {@link MeasureTextOptions} onto the internal run-option shape. */
|
|
1164
1173
|
function measureOptsToRunOpts(opts) {
|
|
1165
1174
|
return pickDefined(opts, [
|
|
@@ -1201,7 +1210,7 @@ function formatCodepoints(cps) {
|
|
|
1201
1210
|
return all.length > shown.length ? `${shown.join(" ")} +${all.length - shown.length} more` : shown.join(" ");
|
|
1202
1211
|
}
|
|
1203
1212
|
/**
|
|
1204
|
-
* Layout-time text measurement against registered metrics
|
|
1213
|
+
* Layout-time text measurement against registered metrics: the public engine
|
|
1205
1214
|
* behind `pptx.measureText()`. Uses the **same** calibrated wrap model, resolver
|
|
1206
1215
|
* semantics, and conservative safety factors as the export-time bake
|
|
1207
1216
|
* (`applyMeasuredFit` / {@link solveResize} / {@link solveShrink}), so a
|
|
@@ -1218,7 +1227,7 @@ function formatCodepoints(cps) {
|
|
|
1218
1227
|
* and is reported in `approximatedFaces`; an unnamed theme-default face returns
|
|
1219
1228
|
* `measurable: false`. Code points a *registered* face has no glyph for are reported
|
|
1220
1229
|
* in `uncoveredCodepoints`, and are the one case where the height may come back short
|
|
1221
|
-
* rather than tall
|
|
1230
|
+
* rather than tall: there is no font fallback here, only the font's `.notdef` advance.
|
|
1222
1231
|
*/
|
|
1223
1232
|
function measureText(registry, text, opts) {
|
|
1224
1233
|
const inset = opts.insetIn ?? 0;
|
|
@@ -1308,13 +1317,13 @@ function applyMeasuredFit(slides, registry) {
|
|
|
1308
1317
|
const collectUnmeasured = (paragraphs, into) => {
|
|
1309
1318
|
for (const para of paragraphs) for (const run of para.runs) if (!resolve(run)) into.add(run.fontFace ?? "(theme default)");
|
|
1310
1319
|
};
|
|
1311
|
-
/** Audit every set of runs the pass is about to measure
|
|
1320
|
+
/** Audit every set of runs the pass is about to measure (see the warning below). */
|
|
1312
1321
|
const auditCoverage = (paragraphs) => collectUncoveredCodepoints(paragraphs, registry, uncoveredByFace);
|
|
1313
1322
|
/**
|
|
1314
1323
|
* Bake measured shrink into a table's cells. Walks the cell grid (accounting for
|
|
1315
1324
|
* colspan/rowspan) to size each cell's box from its column widths and row heights,
|
|
1316
1325
|
* then lowers the run font sizes of any `fit:'shrink'` cell that overflows. Cells
|
|
1317
|
-
* in auto-height rows (no fixed `rowH`/table `h`) are skipped
|
|
1326
|
+
* in auto-height rows (no fixed `rowH`/table `h`) are skipped. The row grows instead.
|
|
1318
1327
|
*/
|
|
1319
1328
|
const measureTableCells = (tableObj, layout) => {
|
|
1320
1329
|
const rows = tableObj.arrTabRows;
|
|
@@ -1410,14 +1419,14 @@ function applyMeasuredFit(slides, registry) {
|
|
|
1410
1419
|
} else collectUnmeasured(paragraphs, unmeasuredResize);
|
|
1411
1420
|
}
|
|
1412
1421
|
};
|
|
1413
|
-
for (const slide of slides) for (const obj of slide._slideObjects
|
|
1414
|
-
if (unmeasuredShrink.size > 0) warn("measure/shrink-unmeasured", `fit:'shrink' could not be measured for font(s) [${[...unmeasuredShrink].join(", ")}]
|
|
1415
|
-
if (unmeasuredResize.size > 0) warn("measure/resize-unmeasured", `fit:'resize' could not be measured for font(s) [${[...unmeasuredResize].join(", ")}]
|
|
1422
|
+
for (const slide of slides) for (const obj of slide._slideObjects) measureObject(obj, slide._presLayout);
|
|
1423
|
+
if (unmeasuredShrink.size > 0) warn("measure/shrink-unmeasured", `fit:'shrink' could not be measured for font(s) [${[...unmeasuredShrink].join(", ")}]: no registered metrics. Emitting bare <a:normAutofit/> (text will not pre-shrink in headless renders). Call pptx.registerFontMetrics(face, fontFilePathOrBytes) to enable measured fit.`);
|
|
1424
|
+
if (unmeasuredResize.size > 0) warn("measure/resize-unmeasured", `fit:'resize' could not be measured for font(s) [${[...unmeasuredResize].join(", ")}]: no registered metrics. Emitting bare <a:spAutoFit/> with the authored height (box will not auto-grow in headless renders). Call pptx.registerFontMetrics(face, fontFilePathOrBytes) to enable measured fit.`);
|
|
1416
1425
|
if (uncoveredByFace.size > 0) {
|
|
1417
1426
|
const perFace = [...uncoveredByFace].map(([face, cps]) => `${face} → ${formatCodepoints(cps)}`).join("; ");
|
|
1418
|
-
warn("measure/uncovered-codepoints", `Measured fit charged the .notdef advance for code point(s) the registered face does not cover (${perFace})
|
|
1427
|
+
warn("measure/uncovered-codepoints", `Measured fit charged the .notdef advance for code point(s) the registered face does not cover (${perFace}). PowerPoint renders those from a substituted font, so the measured width can be wrong in EITHER direction. Too narrow drops a line and the text overflows the baked size, the one case measured fit does not err safe. Register a face that covers them, or set an explicit fontFace on those runs.`);
|
|
1419
1428
|
}
|
|
1420
|
-
if (heuristicFaces.size > 0) warn("measure/heuristic-metrics", `Note: measured fit used a conservative average-advance estimate for font(s) [${[...heuristicFaces].join(", ")}]
|
|
1429
|
+
if (heuristicFaces.size > 0) warn("measure/heuristic-metrics", `Note: measured fit used a conservative average-advance estimate for font(s) [${[...heuristicFaces].join(", ")}]: no exact metrics registered. Fit is approximate (may shrink/grow more than necessary). Call pptx.registerFontMetrics(face, fontFilePathOrBytes) for an exact fit.`);
|
|
1421
1430
|
return restore;
|
|
1422
1431
|
}
|
|
1423
1432
|
/**
|
|
@@ -1432,7 +1441,6 @@ function restorer(target, key) {
|
|
|
1432
1441
|
else delete target[key];
|
|
1433
1442
|
};
|
|
1434
1443
|
}
|
|
1435
|
-
//#endregion
|
|
1436
1444
|
export { getHeuristicFontMetrics as _, CELL_INHERITED_KEYS as a, isFontCollection as b, HEIGHT_SAFETY_FACTOR as c, WIDTH_SAFETY_FACTOR as d, measureHeightPt as f, FontMetricsRegistry as g, solveShrink as h, computeTableLayout as i, MIN_FONT_SCALE_PCT as l, solveResize as m, measureText as n, buildFitParagraphs as o, measureLayout as p, requireBoxHeight as r, FONT_SCALE_STEP_PCT as s, applyMeasuredFit as t, SINGLE_LINE_PITCH as u, makeRegistryResolver as v, listFontFaces as x, parseFontMetrics as y };
|
|
1437
1445
|
|
|
1438
|
-
//# sourceMappingURL=fit-
|
|
1446
|
+
//# sourceMappingURL=fit-Bpmzep6O.js.map
|