@file-viewer/doc 2.1.10

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.
@@ -0,0 +1,73 @@
1
+ export declare const DOC_CONTROL: {
2
+ paragraph: string;
3
+ cellMark: string;
4
+ picture: string;
5
+ fieldStart: string;
6
+ fieldSeparator: string;
7
+ fieldEnd: string;
8
+ annotationRef: string;
9
+ hardLineBreak: string;
10
+ pageBreak: string;
11
+ nonBreakingHyphen: string;
12
+ nonRequiredHyphen: string;
13
+ };
14
+ export declare const UNDERLINE_MAP: {
15
+ 0: string;
16
+ 1: string;
17
+ 2: string;
18
+ 3: string;
19
+ 4: string;
20
+ 5: string;
21
+ 6: string;
22
+ 7: string;
23
+ 9: string;
24
+ 10: string;
25
+ 11: string;
26
+ 16: string;
27
+ 17: string;
28
+ 18: string;
29
+ 19: string;
30
+ 20: string;
31
+ 21: string;
32
+ 22: string;
33
+ 23: string;
34
+ };
35
+ export declare const JC_MAP: {
36
+ 0: string;
37
+ 1: string;
38
+ 2: string;
39
+ 3: string;
40
+ 4: string;
41
+ };
42
+ export declare const VERTICAL_ALIGN_MAP: {
43
+ 0: string;
44
+ 1: string;
45
+ 2: string;
46
+ };
47
+ export declare const HIGHLIGHT_COLORS: {
48
+ 1: string;
49
+ 2: string;
50
+ 3: string;
51
+ 4: string;
52
+ 5: string;
53
+ 6: string;
54
+ 7: string;
55
+ 8: string;
56
+ 9: string;
57
+ 10: string;
58
+ 11: string;
59
+ 12: string;
60
+ 13: string;
61
+ 14: string;
62
+ 15: string;
63
+ 16: string;
64
+ };
65
+ export declare const DEFAULT_FONT_FAMILIES: {
66
+ 0: string;
67
+ };
68
+ export declare const FIELD_TYPES: {
69
+ HYPERLINK: string;
70
+ INCLUDEPICTURE: string;
71
+ EMBED: string;
72
+ LINK: string;
73
+ };
@@ -0,0 +1,73 @@
1
+ export const DOC_CONTROL = {
2
+ paragraph: '\u000d',
3
+ cellMark: '\u0007',
4
+ picture: '\u0001',
5
+ fieldStart: '\u0013',
6
+ fieldSeparator: '\u0014',
7
+ fieldEnd: '\u0015',
8
+ annotationRef: '\u0005',
9
+ hardLineBreak: '\u000b',
10
+ pageBreak: '\u000c',
11
+ nonBreakingHyphen: '\u001e',
12
+ nonRequiredHyphen: '\u001f',
13
+ };
14
+ export const UNDERLINE_MAP = {
15
+ 0: 'none',
16
+ 1: 'single',
17
+ 2: 'word',
18
+ 3: 'double',
19
+ 4: 'dotted',
20
+ 5: 'hidden',
21
+ 6: 'thick',
22
+ 7: 'dash',
23
+ 9: 'dot-dash',
24
+ 10: 'dot-dot-dash',
25
+ 11: 'wave',
26
+ 16: 'dotted-heavy',
27
+ 17: 'dashed-heavy',
28
+ 18: 'dash-long',
29
+ 19: 'dash-long-heavy',
30
+ 20: 'dot-dash-heavy',
31
+ 21: 'dot-dot-dash-heavy',
32
+ 22: 'wavy-heavy',
33
+ 23: 'wavy-double',
34
+ };
35
+ export const JC_MAP = {
36
+ 0: 'left',
37
+ 1: 'center',
38
+ 2: 'right',
39
+ 3: 'justify',
40
+ 4: 'distributed',
41
+ };
42
+ export const VERTICAL_ALIGN_MAP = {
43
+ 0: 'top',
44
+ 1: 'center',
45
+ 2: 'bottom',
46
+ };
47
+ export const HIGHLIGHT_COLORS = {
48
+ 1: '#000000',
49
+ 2: '#0000ff',
50
+ 3: '#00ffff',
51
+ 4: '#00ff00',
52
+ 5: '#ff00ff',
53
+ 6: '#ff0000',
54
+ 7: '#ffff00',
55
+ 8: '#ffffff',
56
+ 9: '#000080',
57
+ 10: '#008080',
58
+ 11: '#008000',
59
+ 12: '#800080',
60
+ 13: '#800000',
61
+ 14: '#808000',
62
+ 15: '#808080',
63
+ 16: '#c0c0c0',
64
+ };
65
+ export const DEFAULT_FONT_FAMILIES = {
66
+ 0: 'serif',
67
+ };
68
+ export const FIELD_TYPES = {
69
+ HYPERLINK: 'hyperlink',
70
+ INCLUDEPICTURE: 'includePicture',
71
+ EMBED: 'embed',
72
+ LINK: 'link',
73
+ };
@@ -0,0 +1,4 @@
1
+ import { BinaryReader } from '../core/binary.js';
2
+ import type { FibBase, ParsedFib } from '../types.js';
3
+ export declare function parseFib(wordBytes: Uint8Array): ParsedFib;
4
+ export declare function parseFibBase(reader: BinaryReader): FibBase;
@@ -0,0 +1,125 @@
1
+ import { BinaryReader } from '../core/binary.js';
2
+ const FIB_FC_LCB_NAMES = [
3
+ 'StshfOrig', 'Stshf', 'PlcffndRef', 'PlcffndTxt', 'PlcfandRef', 'PlcfandTxt',
4
+ 'PlcfSed', 'PlcPad', 'PlcfPhe', 'SttbfGlsy', 'PlcfGlsy', 'PlcfHdd', 'PlcfBteChpx',
5
+ 'PlcfBtePapx', 'PlcfSea', 'SttbfFfn', 'PlcfFldMom', 'PlcfFldHdr', 'PlcfFldFtn',
6
+ 'PlcfFldAtn', 'PlcfFldMcr', 'SttbfBkmk', 'PlcfBkf', 'PlcfBkl', 'Cmds', 'Unused1',
7
+ 'SttbfMcr', 'PrDrvr', 'PrEnvPort', 'PrEnvLand', 'Wss', 'Dop', 'SttbfAssoc', 'Clx',
8
+ 'PlcfPgdFtn', 'AutosaveSource', 'GrpXstAtnOwners', 'SttbfAtnBkmk', 'Unused2',
9
+ 'Unused3', 'PlcSpaMom', 'PlcSpaHdr', 'PlcfAtnBkf', 'PlcfAtnBkl', 'Pms',
10
+ 'FormFldSttbs', 'PlcfendRef', 'PlcfendTxt', 'PlcfFldEdn', 'Unused4', 'DggInfo',
11
+ 'SttbfRMark', 'SttbfCaption', 'SttbfAutoCaption', 'PlcfWkb', 'PlcfSpl',
12
+ 'PlcftxbxTxt', 'PlcfFldTxbx', 'PlcfHdrtxbxTxt', 'PlcffldHdrTxbx', 'StwUser',
13
+ 'SttbTtmbd', 'CookieData', 'PgdMotherOldOld', 'BkdMotherOldOld', 'PgdFtnOldOld',
14
+ 'BkdFtnOldOld', 'PgdEdnOldOld', 'BkdEdnOldOld', 'SttbfIntlFld', 'RouteSlip',
15
+ 'SttbSavedBy', 'SttbFnm', 'PlfLst', 'PlfLfo', 'PlcfTxbxBkd', 'PlcfTxbxHdrBkd',
16
+ 'DocUndoWord9', 'RgbUse', 'Usp', 'Uskf', 'PlcupcRgbUse', 'PlcupcUsp', 'SttbGlsyStyle',
17
+ 'Plgosl', 'Plcocx', 'PlcfBteLvc', 'dwLowDateTime', 'dwHighDateTime', 'PlcfLvcPre10',
18
+ 'PlcfAsumy', 'PlcfGram', 'SttbListNames', 'SttbfUssr',
19
+ ];
20
+ export function parseFib(wordBytes) {
21
+ const reader = new BinaryReader(wordBytes);
22
+ const base = parseFibBase(reader);
23
+ let offset = 32;
24
+ const csw = reader.u16(offset);
25
+ offset += 2;
26
+ const fibRgWBytes = reader.slice(offset, csw * 2);
27
+ offset += csw * 2;
28
+ const cslw = reader.u16(offset);
29
+ offset += 2;
30
+ const fibRgLwBytes = reader.slice(offset, cslw * 4);
31
+ offset += cslw * 4;
32
+ const cbRgFcLcb = reader.u16(offset);
33
+ offset += 2;
34
+ const fibRgFcLcbBytes = reader.slice(offset, cbRgFcLcb * 8);
35
+ offset += cbRgFcLcb * 8;
36
+ const cswNew = reader.ensure(offset, 2) ? reader.u16(offset) : 0;
37
+ if (reader.ensure(offset, 2))
38
+ offset += 2;
39
+ const fibRgCswNewBytes = cswNew ? reader.slice(offset, cswNew * 2) : new Uint8Array(0);
40
+ const fibRgLw = parseFibRgLw(fibRgLwBytes);
41
+ const fibRgFcLcb = parseFibRgFcLcb(fibRgFcLcbBytes, cbRgFcLcb);
42
+ const nFibNew = cswNew ? new BinaryReader(fibRgCswNewBytes).u16(0) : 0;
43
+ return {
44
+ base,
45
+ csw,
46
+ cslw,
47
+ cbRgFcLcb,
48
+ cswNew,
49
+ nFibNew,
50
+ fibRgWBytes,
51
+ fibRgLwBytes,
52
+ fibRgFcLcbBytes,
53
+ fibRgCswNewBytes,
54
+ fibRgLw,
55
+ fibRgFcLcb,
56
+ };
57
+ }
58
+ export function parseFibBase(reader) {
59
+ const wIdent = reader.u16(0);
60
+ const nFib = reader.u16(2);
61
+ const lid = reader.u16(6);
62
+ const pnNext = reader.u16(8);
63
+ const flags = reader.u16(10);
64
+ const envFlags = reader.u16(18);
65
+ return {
66
+ wIdent,
67
+ nFib,
68
+ lid,
69
+ pnNext,
70
+ flags,
71
+ envFlags,
72
+ fDot: Boolean(flags & 0x0001),
73
+ fGlsy: Boolean(flags & 0x0002),
74
+ fComplex: Boolean(flags & 0x0004),
75
+ fHasPic: Boolean(flags & 0x0008),
76
+ cQuickSaves: (flags >> 4) & 0x0f,
77
+ fEncrypted: Boolean(flags & 0x0100),
78
+ fWhichTblStm: Boolean(flags & 0x0200) ? 1 : 0,
79
+ fReadOnlyRecommended: Boolean(flags & 0x0400),
80
+ fWriteReservation: Boolean(flags & 0x0800),
81
+ fExtChar: Boolean(flags & 0x1000),
82
+ fLoadOverride: Boolean(flags & 0x2000),
83
+ fFarEast: Boolean(flags & 0x4000),
84
+ fObfuscated: Boolean(flags & 0x8000),
85
+ nFibBack: reader.u16(12),
86
+ lKey: reader.u32(14),
87
+ envr: reader.u8(18),
88
+ fMac: Boolean(envFlags & 0x0001),
89
+ fEmptySpecial: Boolean(envFlags & 0x0002),
90
+ fLoadOverridePage: Boolean(envFlags & 0x0004),
91
+ };
92
+ }
93
+ function parseFibRgLw(bytes) {
94
+ const reader = new BinaryReader(bytes);
95
+ const dwords = [];
96
+ for (let i = 0; i + 4 <= bytes.length; i += 4)
97
+ dwords.push(reader.i32(i));
98
+ return {
99
+ raw: dwords,
100
+ cbMac: dwords[0] ?? 0,
101
+ ccpText: dwords[3] ?? 0,
102
+ ccpFtn: dwords[4] ?? 0,
103
+ ccpHdd: dwords[5] ?? 0,
104
+ ccpMcr: dwords[6] ?? 0,
105
+ ccpAtn: dwords[7] ?? 0,
106
+ ccpEdn: dwords[8] ?? 0,
107
+ ccpTxbx: dwords[9] ?? 0,
108
+ ccpHdrTxbx: dwords[10] ?? 0,
109
+ };
110
+ }
111
+ function parseFibRgFcLcb(bytes, count) {
112
+ const reader = new BinaryReader(bytes);
113
+ const fields = { _pairs: [] };
114
+ const pairs = [];
115
+ for (let i = 0; i < count && i * 8 + 8 <= bytes.length; i += 1) {
116
+ const fc = reader.u32(i * 8);
117
+ const lcb = reader.u32(i * 8 + 4);
118
+ const name = FIB_FC_LCB_NAMES[i] || `Field${i}`;
119
+ fields[`fc${name}`] = fc;
120
+ fields[`lcb${name}`] = lcb;
121
+ pairs.push({ name, fc, lcb, index: i });
122
+ }
123
+ fields._pairs = pairs;
124
+ return fields;
125
+ }
@@ -0,0 +1,19 @@
1
+ import type { DecodedProperty, ParsedClx, ParsedFib } from '../types.js';
2
+ export interface ChpxRun {
3
+ cpStart: number;
4
+ cpEnd: number;
5
+ fcStart: number;
6
+ fcEnd: number;
7
+ properties: DecodedProperty[];
8
+ }
9
+ export interface PapxRun extends ChpxRun {
10
+ styleId: number;
11
+ rawOffset: number;
12
+ }
13
+ export declare function readChpxRuns(wordBytes: Uint8Array, tableBytes: Uint8Array, fib: ParsedFib, clx: ParsedClx): ChpxRun[];
14
+ export declare function readPapxRuns(wordBytes: Uint8Array, tableBytes: Uint8Array, fib: ParsedFib, clx: ParsedClx, dataBytes?: Uint8Array): PapxRun[];
15
+ export declare function readChpxProperties(wordBytes: Uint8Array, offset: number | null | undefined): DecodedProperty[];
16
+ export declare function readPapxProperties(wordBytes: Uint8Array, offset: number | null | undefined, dataBytes?: Uint8Array): {
17
+ styleId: number;
18
+ properties: DecodedProperty[];
19
+ };
@@ -0,0 +1,184 @@
1
+ import { BinaryReader } from '../core/binary.js';
2
+ import { decodeGrpprl, SprmCodes } from './sprm.js';
3
+ import { fcToCp } from './clx.js';
4
+ function u32(bytes, offset = 0) {
5
+ if (offset + 4 > bytes.length)
6
+ return 0;
7
+ return ((bytes[offset] ?? 0)
8
+ | ((bytes[offset + 1] ?? 0) << 8)
9
+ | ((bytes[offset + 2] ?? 0) << 16)
10
+ | (((bytes[offset + 3] ?? 0) << 24) >>> 0)) >>> 0;
11
+ }
12
+ function readPlcBte(tableBytes, fc, lcb) {
13
+ if (fc == null || lcb == null || lcb <= 0)
14
+ return { aFC: [], pages: [] };
15
+ const bytes = tableBytes.subarray(fc, fc + lcb);
16
+ const reader = new BinaryReader(bytes);
17
+ const count = Math.floor((lcb - 4) / 8);
18
+ if (count <= 0)
19
+ return { aFC: [], pages: [] };
20
+ const aFC = [];
21
+ for (let i = 0; i <= count; i += 1)
22
+ aFC.push(reader.u32(i * 4) >>> 0);
23
+ const pages = [];
24
+ const pnOffset = (count + 1) * 4;
25
+ for (let i = 0; i < count; i += 1)
26
+ pages.push(reader.u32(pnOffset + i * 4) & 0x3fffff);
27
+ return { aFC, pages };
28
+ }
29
+ function readChpxFkp(wordBytes, pn) {
30
+ const offset = pn * 512;
31
+ const page = wordBytes.subarray(offset, offset + 512);
32
+ if (page.length < 512)
33
+ return null;
34
+ const reader = new BinaryReader(page);
35
+ const crun = reader.u8(511);
36
+ if (!crun || crun > 100)
37
+ return null;
38
+ const rgfc = [];
39
+ for (let i = 0; i <= crun; i += 1)
40
+ rgfc.push(reader.u32(i * 4) >>> 0);
41
+ const rgb = [];
42
+ const chpxOffsets = [];
43
+ const rgbStart = (crun + 1) * 4;
44
+ for (let i = 0; i < crun; i += 1) {
45
+ const b = reader.u8(rgbStart + i);
46
+ rgb.push(b);
47
+ chpxOffsets.push(b ? offset + b * 2 : 0);
48
+ }
49
+ return { crun, rgfc, rgb, chpxOffsets };
50
+ }
51
+ function readPapxFkp(wordBytes, pn) {
52
+ const offset = pn * 512;
53
+ const page = wordBytes.subarray(offset, offset + 512);
54
+ if (page.length < 512)
55
+ return null;
56
+ const reader = new BinaryReader(page);
57
+ const cpara = reader.u8(511);
58
+ if (cpara > 0x1d)
59
+ return null;
60
+ const rgfc = [];
61
+ for (let i = 0; i <= cpara; i += 1)
62
+ rgfc.push(reader.u32(i * 4) >>> 0);
63
+ const bxStart = (cpara + 1) * 4;
64
+ const bOffsets = [];
65
+ const papxOffsets = [];
66
+ for (let i = 0; i < cpara; i += 1) {
67
+ const bOffset = reader.u8(bxStart + i * 13);
68
+ bOffsets.push(bOffset);
69
+ papxOffsets.push(bOffset ? offset + bOffset * 2 : 0);
70
+ }
71
+ return { cpara, rgfc, bOffsets, papxOffsets };
72
+ }
73
+ export function readChpxRuns(wordBytes, tableBytes, fib, clx) {
74
+ const fcPlcfBteChpx = fib.fibRgFcLcb.fcPlcfBteChpx;
75
+ const lcbPlcfBteChpx = fib.fibRgFcLcb.lcbPlcfBteChpx;
76
+ const plc = readPlcBte(tableBytes, fcPlcfBteChpx, lcbPlcfBteChpx);
77
+ const runs = [];
78
+ for (const pn of plc.pages) {
79
+ const fkp = readChpxFkp(wordBytes, pn);
80
+ if (!fkp)
81
+ continue;
82
+ for (let i = 0; i < fkp.crun; i += 1) {
83
+ const fcStart = fkp.rgfc[i] ?? 0;
84
+ const fcEnd = fkp.rgfc[i + 1] ?? fcStart;
85
+ const cpStart = fcToCp(clx, fcStart);
86
+ const cpEnd = fcToCp(clx, fcEnd);
87
+ if (cpStart == null || cpEnd == null || cpEnd <= cpStart)
88
+ continue;
89
+ const properties = fkp.chpxOffsets[i] ? readChpxProperties(wordBytes, fkp.chpxOffsets[i]) : [];
90
+ runs.push({ cpStart, cpEnd, fcStart, fcEnd, properties });
91
+ }
92
+ }
93
+ runs.sort((a, b) => a.cpStart - b.cpStart || a.cpEnd - b.cpEnd);
94
+ return runs;
95
+ }
96
+ export function readPapxRuns(wordBytes, tableBytes, fib, clx, dataBytes) {
97
+ const fcPlcfBtePapx = fib.fibRgFcLcb.fcPlcfBtePapx;
98
+ const lcbPlcfBtePapx = fib.fibRgFcLcb.lcbPlcfBtePapx;
99
+ const plc = readPlcBte(tableBytes, fcPlcfBtePapx, lcbPlcfBtePapx);
100
+ const runs = [];
101
+ for (const pn of plc.pages) {
102
+ const fkp = readPapxFkp(wordBytes, pn);
103
+ if (!fkp)
104
+ continue;
105
+ for (let i = 0; i < fkp.cpara; i += 1) {
106
+ const fcStart = fkp.rgfc[i] ?? 0;
107
+ const fcEnd = fkp.rgfc[i + 1] ?? fcStart;
108
+ const cpStart = fcToCp(clx, fcStart);
109
+ const cpEnd = fcToCp(clx, fcEnd);
110
+ if (cpStart == null || cpEnd == null || cpEnd < cpStart)
111
+ continue;
112
+ const papx = fkp.papxOffsets[i]
113
+ ? readPapxProperties(wordBytes, fkp.papxOffsets[i], dataBytes)
114
+ : { styleId: 0, properties: [] };
115
+ runs.push({ cpStart, cpEnd, fcStart, fcEnd, styleId: papx.styleId, properties: papx.properties, rawOffset: fkp.papxOffsets[i] ?? 0 });
116
+ }
117
+ }
118
+ runs.sort((a, b) => a.cpStart - b.cpStart || a.cpEnd - b.cpEnd);
119
+ return runs;
120
+ }
121
+ export function readChpxProperties(wordBytes, offset) {
122
+ if (offset == null || offset < 0 || offset >= wordBytes.length)
123
+ return [];
124
+ const cb = wordBytes[offset] ?? 0;
125
+ if (!cb)
126
+ return [];
127
+ const start = offset + 1;
128
+ const end = Math.min(wordBytes.length, start + cb);
129
+ return decodeGrpprl(wordBytes, start, end);
130
+ }
131
+ function readHugePapxProperties(dataBytes, offset) {
132
+ if (offset < 0 || offset + 2 > dataBytes.length)
133
+ return [];
134
+ const cb = (dataBytes[offset] ?? 0) | ((dataBytes[offset + 1] ?? 0) << 8);
135
+ if (!cb || offset + 2 + cb > dataBytes.length)
136
+ return [];
137
+ return decodeGrpprl(dataBytes, offset + 2, offset + 2 + cb);
138
+ }
139
+ function expandHugePapxProperties(properties, dataBytes) {
140
+ if (!dataBytes?.length)
141
+ return properties;
142
+ const expanded = [];
143
+ for (const property of properties) {
144
+ if (property.raw !== SprmCodes.sprmPHugePapx) {
145
+ expanded.push(property);
146
+ continue;
147
+ }
148
+ const operandBytes = property.operandBytes || (property.value instanceof Uint8Array ? property.value : null);
149
+ if (!operandBytes || operandBytes.length < 4) {
150
+ expanded.push(property);
151
+ continue;
152
+ }
153
+ const hugeOffset = u32(operandBytes);
154
+ const hugeProperties = readHugePapxProperties(dataBytes, hugeOffset);
155
+ expanded.push(...(hugeProperties.length ? hugeProperties : [property]));
156
+ }
157
+ return expanded;
158
+ }
159
+ export function readPapxProperties(wordBytes, offset, dataBytes) {
160
+ if (offset == null || offset < 0 || offset >= wordBytes.length)
161
+ return { styleId: 0, properties: [] };
162
+ const reader = new BinaryReader(wordBytes);
163
+ const cb = reader.u8(offset);
164
+ if (cb === 0 && !reader.ensure(offset + 1, 1))
165
+ return { styleId: 0, properties: [] };
166
+ let bodyStart;
167
+ let bodySize;
168
+ if (cb === 0) {
169
+ bodySize = reader.u8(offset + 1) * 2;
170
+ bodyStart = offset + 2;
171
+ }
172
+ else {
173
+ bodySize = cb - 1;
174
+ bodyStart = offset + 1;
175
+ }
176
+ if (bodySize < 2 || !reader.ensure(bodyStart, Math.max(2, bodySize))) {
177
+ return { styleId: 0, properties: [] };
178
+ }
179
+ const styleId = reader.u16(bodyStart);
180
+ const propsStart = bodyStart + 2;
181
+ const propsEnd = Math.min(wordBytes.length, bodyStart + bodySize);
182
+ const properties = expandHugePapxProperties(decodeGrpprl(wordBytes, propsStart, propsEnd), dataBytes);
183
+ return { styleId, properties };
184
+ }
@@ -0,0 +1,2 @@
1
+ import type { FibRgFcLcb, FontsCollection } from '../types.js';
2
+ export declare function parseFonts(tableBytes: Uint8Array, fibRgFcLcb: FibRgFcLcb): FontsCollection;
@@ -0,0 +1,87 @@
1
+ import { BinaryReader } from '../core/binary.js';
2
+ function decodeUtf16Z(bytes, offset) {
3
+ let end = offset;
4
+ while (end + 1 < bytes.length) {
5
+ if (bytes[end] === 0 && bytes[end + 1] === 0)
6
+ break;
7
+ end += 2;
8
+ }
9
+ const text = new TextDecoder('utf-16le').decode(bytes.subarray(offset, end));
10
+ return { value: text, nextOffset: Math.min(bytes.length, end + 2) };
11
+ }
12
+ function parseFfn(recordBytes, index) {
13
+ if (!recordBytes.length)
14
+ return null;
15
+ const reader = new BinaryReader(recordBytes);
16
+ const cbFfnM1 = reader.u8(0);
17
+ const ffid = reader.u8(1);
18
+ const wWeight = reader.u16(2);
19
+ const chs = reader.u8(4);
20
+ const ixchSzAlt = reader.u8(5);
21
+ const panose = reader.slice(6, 10);
22
+ const fontSignature = reader.slice(16, 24);
23
+ const namesOffset = 40;
24
+ let name = '';
25
+ let altName = '';
26
+ if (recordBytes.length > namesOffset) {
27
+ const full = new TextDecoder('utf-16le').decode(recordBytes.subarray(namesOffset));
28
+ const parts = full.split('\u0000').filter(Boolean);
29
+ name = parts[0] || '';
30
+ altName = parts[1] || '';
31
+ if (!altName && ixchSzAlt) {
32
+ const altOffset = namesOffset + ixchSzAlt * 2;
33
+ if (altOffset + 2 <= recordBytes.length) {
34
+ altName = decodeUtf16Z(recordBytes, altOffset).value;
35
+ }
36
+ }
37
+ }
38
+ return {
39
+ index,
40
+ cbFfnM1,
41
+ ffid,
42
+ weight: wWeight,
43
+ charset: chs,
44
+ ixchSzAlt,
45
+ panose,
46
+ fontSignature,
47
+ name,
48
+ altName,
49
+ };
50
+ }
51
+ export function parseFonts(tableBytes, fibRgFcLcb) {
52
+ const fcSttbfFfn = fibRgFcLcb.fcSttbfFfn;
53
+ const lcbSttbfFfn = fibRgFcLcb.lcbSttbfFfn;
54
+ if (fcSttbfFfn == null || lcbSttbfFfn == null || lcbSttbfFfn <= 0) {
55
+ return {
56
+ header: null,
57
+ fonts: [],
58
+ byIndex(index) {
59
+ return index == null ? null : null;
60
+ },
61
+ };
62
+ }
63
+ const bytes = tableBytes.subarray(fcSttbfFfn, fcSttbfFfn + lcbSttbfFfn);
64
+ const reader = new BinaryReader(bytes);
65
+ const cData = reader.u16(0);
66
+ const cbExtra = reader.u16(2);
67
+ let offset = 4;
68
+ const fonts = [];
69
+ for (let i = 0; i < cData && offset < bytes.length; i += 1) {
70
+ const cbFfnM1 = reader.u8(offset);
71
+ const recordLength = cbFfnM1 + 1;
72
+ const recordBytes = bytes.subarray(offset, Math.min(offset + recordLength, bytes.length));
73
+ const font = parseFfn(recordBytes, i);
74
+ if (font)
75
+ fonts.push(font);
76
+ offset += recordLength + cbExtra;
77
+ }
78
+ return {
79
+ header: { cData, cbExtra },
80
+ fonts,
81
+ byIndex(index) {
82
+ if (index == null || index < 0)
83
+ return null;
84
+ return fonts[index] || null;
85
+ },
86
+ };
87
+ }
@@ -0,0 +1,15 @@
1
+ import type { ImageAsset, MsDocParseOptions, ObjectPoolInfo, ParsedCFB } from '../types.js';
2
+ export declare function detectImageSegment(bytes: Uint8Array): {
3
+ mime: string;
4
+ start: number;
5
+ end: number;
6
+ } | null;
7
+ export declare function extractPictureAsset(dataStreamBytes: Uint8Array, pictureOffset: number | null | undefined, options?: MsDocParseOptions): ImageAsset | null;
8
+ export declare function parseOle10Native(streamBytes: Uint8Array): {
9
+ label: string;
10
+ originalPath: string;
11
+ tempPath: string;
12
+ dataSize: number;
13
+ bytes: Uint8Array;
14
+ } | null;
15
+ export declare function extractObjectPool(cfb: ParsedCFB): Map<string, ObjectPoolInfo>;