import { ParagraphProperties, RunProperties } from '../core/document-model/index.js'; import { ColorResolver } from '../core/drawingml/colors.js'; import { ThemeFonts } from '../core/drawingml/theme-parser.js'; import { PoNode } from '../core/po-helpers.js'; import { PlaceholderRef, ShapeBoxEmu } from './sp-helpers.js'; import { Pt } from '../core/ir/index.js'; /** * The placeholder cascade (PX2): the resolver a slide parser consults whenever a * slide placeholder shape (`p:sp` with a `p:ph`) lacks its own geometry or run * formatting, supplying the inherited values from the slide's layout, then its * master. */ export interface PlaceholderCascade { /** The inherited EMU box for a slide placeholder without its own `a:xfrm`. */ readonly geometryFor: (ph: PlaceholderRef) => ShapeBoxEmu | undefined; /** * The inherited run formatting for a paragraph at the given 0-based outline * level. Without a placeholder this is the presentation's default text style * — what an ordinary text box on a slide is written in. */ readonly defaultsFor: (ph: PlaceholderRef | undefined, level: number) => RunProperties; /** The inherited paragraph shape at that level: alignment, indent, spacing. */ readonly paragraphDefaultsFor: (ph: PlaceholderRef | undefined, level: number) => ParagraphProperties; /** The bullet that level inherits, which a paragraph states only to change. */ readonly bulletFor: (ph: PlaceholderRef | undefined, level: number) => LevelBullet | undefined; /** * The vertical anchor the placeholder's prototype states (`a:bodyPr@anchor`), * the layout's before the master's, for a shape that states none itself. */ readonly anchorFor: (ph: PlaceholderRef) => 't' | 'ctr' | 'b' | undefined; /** * The prototypes' own `p:spPr`, nearest first — the layout's, then the * master's — for the properties a slide placeholder inherits rather than * states: its fill, its outline, its geometry. * * A CHAIN and not one node, because the inheritance is per property. The * layout's prototype may state a box and nothing else, and the fill then * comes from the master: tdf104015's title is red in every reader and was a * bare outline here, because the layout's `p:spPr` existed and stopped the * search. */ readonly shapePropsFor: (ph: PlaceholderRef) => ReadonlyArray; } /** One level of a text style: how its paragraphs sit and how their runs read. */ interface LevelStyle { readonly run: RunProperties; readonly paragraph: ParagraphProperties; readonly bullet?: LevelBullet; /** * §21.1.2.2.9/.10 — the space around the paragraph stated as a FRACTION of a * line rather than a distance. A fraction of WHAT is only known once the * levels have merged and the size is settled, so it travels this far raw. */ readonly spacingPct?: { readonly before?: number; readonly after?: number; }; } /** * §21.1.2.4.4/.5/.6 — the bullet a level declares: none at all, a literal * character, or a number that counts. A slide paragraph states one only where * it differs from this: themes.pptx's second slide writes one bare line, and * the dot in front of it is the master's body style, nine levels up. */ export interface LevelBullet { /** What it draws: nothing at all, a character, or a number that counts. */ readonly kind?: 'none' | 'char' | 'autoNum'; /** `a:buChar` — the character, already read out of the face that states it. */ readonly char?: string; /** `a:buAutoNum @type`/`@startAt` — the numbering and where it starts. */ readonly type?: string; readonly startAt?: number; /** §21.1.2.4.2/.3 — its size, as a fraction of the text or in points. */ readonly sizePct?: number; readonly sizePts?: number; /** §21.1.2.4.1 `a:buClr` — the colour it is drawn in, when it has its own. */ readonly colorHex?: string; } /** * What an `a:pPr` (or an `a:lvlNpPr`, the same vocabulary) says about its * bullet — each part on its own, because a paragraph may restate the SIZE and * leave the character to its level. * * @param pPr The paragraph-properties node. * @param colors The colour resolver, for `a:buClr`. * @returns What it states, or `undefined` when it says nothing about bullets. */ export declare function parseBullet(pPr: PoNode | undefined, colors?: ColorResolver): LevelBullet | undefined; /** * Build a {@link PlaceholderCascade} from a slide's already-parsed layout and * master trees: it resolves a placeholder's inherited geometry (the layout's * matching `a:xfrm`, else the master's) and per-level default run formatting (the * master's `p:txStyles`). * * @param layoutTree The parsed `p:sldLayout` part. * @param masterTree The parsed `p:sldMaster` part, when present. * @param colors The deck's colour resolver, for scheme colours in the text styles. * @param deckDefaults The presentation's own default text style, as the floor. * @param themeFonts The theme's font scheme, for the `+mn-lt` tokens. */ export declare function buildPlaceholderCascade(layoutTree: ReadonlyArray, masterTree: ReadonlyArray | undefined, colors: ColorResolver, deckDefaults?: ReadonlyArray, themeFonts?: ThemeFonts): PlaceholderCascade; /** * §21.1.2.2.9/.10 — the space a paragraph states as a FRACTION of a line, in * points. * * A "line" here is the paragraph's own text at its natural height, which is the * size times the same 1.2 the layout gives an unstated line. A level that * states the fraction and leaves the size to another level is resolved once * they have merged, which is why this is not read where the fraction is. * * @param pct The fraction, `0..n` (20% arrives as 0.2). * @param sizePt The paragraph's resolved font size. * @returns The distance, or `undefined` when the size is not known. */ export declare function spacingFromLineFraction(pct: number | undefined, sizePt: number | undefined): Pt | undefined; /** * `a:lstStyle` (or a `p:txStyles` family) → its nine levels. Shared by the * deck's default text style, the master's families and a prototype's own list, * which are the same vocabulary written in different places. * * @param list The `a:lstStyle` / `p:titleStyle` / … node. * @param colors The deck's colour resolver. * @param prefix The level element prefix: `a:lvl` here, always. * @returns The nine levels, or an empty list when there is no such node. */ export declare function parseLevelStyles(list: PoNode | undefined, colors: ColorResolver, themeFonts?: ThemeFonts): Array; /** * A level's paragraph shape — §21.1.2.2.7 `@algn`, `@marL`/`@indent`, and the * space around and between its lines. * * Both spacings come in two spellings: `a:spcPts` is a distance (hundredths of * a point) and `a:spcPct` a FRACTION of a line (thousandths of a percent). Only * the distance was read, so a deck that spaces its bullets the usual way — by * fraction — set them solid. */ export declare function pPrToParagraphProps(lvlPr: PoNode | undefined): ParagraphProperties; /** * §21.1.2.2.5 `a:lnSpc` — the height of each line: a fraction of the natural * one (`a:spcPct`) or a distance (`a:spcPts`). * * The model states a multiple the way §17.3.1.33 does — 12pt under the `auto` * rule IS single — so a fraction needs no font size to express, which is why * this resolves here and the paragraph SPACING has to wait for the size. * * @param pPr The paragraph properties (a level's or a paragraph's own). * @returns The line spacing, or nothing when the node states none. */ export declare function lineSpacing(pPr: PoNode | undefined): ParagraphProperties; /** * §21.1.2.2.9/.10 — the fraction of a line a paragraph puts before and after * itself, when it states one. The distance form is read beside it; this is what * the caller must still resolve against the size. * * @param pPr The paragraph properties. * @returns The two fractions (`0..n`), each present only when stated. */ export declare function spacingFractions(pPr: PoNode | undefined): { readonly before?: number; readonly after?: number; } | undefined; export {};