reamkit 1.22.0 → 1.23.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/dist/esm/core/converter/ream.d.ts +16 -0
- package/dist/esm/core/converter/ream.js +59 -9
- package/dist/esm/core/document-model/types.d.ts +18 -0
- package/dist/esm/core/drawingml/chart-geometry.js +11 -5
- package/dist/esm/core/drawingml/colors.d.ts +4 -2
- package/dist/esm/core/drawingml/colors.js +15 -0
- package/dist/esm/core/drawingml/theme-parser.d.ts +38 -0
- package/dist/esm/core/drawingml/theme-parser.js +64 -1
- package/dist/esm/core/fonts/families.d.ts +10 -0
- package/dist/esm/core/fonts/families.js +44 -0
- package/dist/esm/core/fonts/index.d.ts +3 -2
- package/dist/esm/core/fonts/remote-fonts.d.ts +50 -0
- package/dist/esm/core/fonts/remote-fonts.js +114 -8
- package/dist/esm/core/fonts/scripts.d.ts +26 -0
- package/dist/esm/core/fonts/scripts.js +177 -0
- package/dist/esm/core/metafile/blit.d.ts +33 -0
- package/dist/esm/core/metafile/blit.js +67 -0
- package/dist/esm/core/metafile/dib.d.ts +61 -0
- package/dist/esm/core/metafile/dib.js +205 -0
- package/dist/esm/core/metafile/emf.js +137 -23
- package/dist/esm/core/metafile/picture.d.ts +12 -1
- package/dist/esm/core/metafile/wmf.js +149 -9
- package/dist/esm/core/ole/escher-blip.d.ts +12 -0
- package/dist/esm/core/ole/escher-blip.js +88 -0
- package/dist/esm/{pdf-reader → core}/png-encode.js +1 -1
- package/dist/esm/excel/print-model.js +3 -1
- package/dist/esm/excel/styles-parser.js +1 -1
- package/dist/esm/excel/xls/biff-reader.js +53 -18
- package/dist/esm/excel/xls/biff-styles.d.ts +5 -2
- package/dist/esm/excel/xls/biff-styles.js +9 -7
- package/dist/esm/excel/xls/escher.js +90 -24
- package/dist/esm/layout/page-doc.d.ts +39 -0
- package/dist/esm/layout/styled-layout.d.ts +2 -2
- package/dist/esm/layout/styled-layout.js +301 -35
- package/dist/esm/pdf/styled-page-emitter.js +35 -2
- package/dist/esm/pdf-reader/image-decode.js +1 -1
- package/dist/esm/pptx/embedded-fonts.d.ts +31 -0
- package/dist/esm/pptx/embedded-fonts.js +104 -0
- package/dist/esm/pptx/placeholder-cascade.d.ts +73 -6
- package/dist/esm/pptx/placeholder-cascade.js +114 -18
- package/dist/esm/pptx/ppt/ppt-reader.js +120 -10
- package/dist/esm/pptx/ppt/ppt-text.d.ts +66 -1
- package/dist/esm/pptx/ppt/ppt-text.js +576 -137
- package/dist/esm/pptx/pptx-reader.d.ts +8 -0
- package/dist/esm/pptx/pptx-reader.js +27 -5
- package/dist/esm/pptx/preset-table-styles.d.ts +9 -0
- package/dist/esm/pptx/preset-table-styles.js +27 -0
- package/dist/esm/pptx/slide-parser.d.ts +7 -1
- package/dist/esm/pptx/slide-parser.js +106 -33
- package/dist/esm/pptx/sp-helpers.d.ts +2 -1
- package/dist/esm/pptx/sp-helpers.js +3 -2
- package/dist/esm/pptx/table-style.d.ts +9 -1
- package/dist/esm/pptx/table-style.js +49 -7
- package/dist/esm/word/document-parser.d.ts +7 -1
- package/dist/esm/word/document-parser.js +6 -6
- package/dist/esm/word/docx-reader.js +6 -3
- package/dist/esm/word/docx-to-pdf.d.ts +8 -7
- package/dist/esm/word/docx-to-pdf.js +25 -7
- package/dist/esm/word/drawing-parser.js +31 -19
- package/dist/esm/word/numbering-parser.d.ts +2 -1
- package/dist/esm/word/numbering-parser.js +6 -6
- package/dist/esm/word/paragraph-properties.d.ts +2 -1
- package/dist/esm/word/paragraph-properties.js +2 -2
- package/dist/esm/word/run-properties.d.ts +5 -2
- package/dist/esm/word/run-properties.js +13 -8
- package/dist/esm/word/styles-parser.d.ts +2 -1
- package/dist/esm/word/styles-parser.js +12 -12
- package/dist/esm/word/table-parser.js +3 -3
- package/dist/esm/word/theme-fonts.d.ts +10 -0
- package/dist/esm/word/theme-fonts.js +28 -0
- package/package.json +1 -1
- /package/dist/esm/{pdf-reader → core}/png-encode.d.ts +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveFamilyStyle } from "../core/fonts/remote-fonts.js";
|
|
2
|
+
import { scriptForCodepoint } from "../core/fonts/scripts.js";
|
|
2
3
|
import { shapeText } from "../core/font/opentype-layout.js";
|
|
3
4
|
import { createFontMeasure } from "../core/font/measure.js";
|
|
4
5
|
import { halfPtToPt, pt } from "../core/ir/units.js";
|
|
@@ -948,8 +949,9 @@ function layoutBodyElement(el, options, fontResources, imageResources, contentWi
|
|
|
948
949
|
if (el.kind === "paragraph") return layoutParagraphBlock(el.paragraph, options, fontResources, imageResources, contentWidth);
|
|
949
950
|
if (el.kind === "table") return layoutTableBlock(el.table, options, fontResources, imageResources, contentWidth);
|
|
950
951
|
if (el.kind === "image") {
|
|
951
|
-
const
|
|
952
|
-
|
|
952
|
+
const res = el.image.resource ? imageResources?.get(el.image.resource) : void 0;
|
|
953
|
+
const meta = res?.metafile;
|
|
954
|
+
return meta ? layoutMetafileBlock(el.image, meta, res.metafileImages, options, fontResources, contentWidth, maxHeight, box) : layoutImageBlock(el.image, imageResources, contentWidth, maxHeight, box);
|
|
953
955
|
}
|
|
954
956
|
if (el.kind === "chart") return layoutChartBlock(el.chart, options, fontResources, contentWidth, maxHeight, imageResources);
|
|
955
957
|
return layoutShapeBlock(el.shape, options, fontResources, imageResources, contentWidth, maxHeight, box);
|
|
@@ -1027,9 +1029,9 @@ function layoutShapeBlock(shape, options, fontResources, imageResources, content
|
|
|
1027
1029
|
const fillGradient = shape.fill.kind === "gradient" ? shape.fill.gradient : void 0;
|
|
1028
1030
|
const fillImage = shape.fill.kind === "picture" && shape.fill.imageResource !== void 0 ? imageResources?.get(shape.fill.imageResource) : void 0;
|
|
1029
1031
|
const fillImageResourceName = fillImage?.resourceName;
|
|
1030
|
-
const fillImageTile = shape.fill.kind === "picture" && shape.fill.tiled === true && fillImage?.prepared ? {
|
|
1031
|
-
widthPt: fillImage.prepared.widthPx * 72 / 96,
|
|
1032
|
-
heightPt: fillImage.prepared.heightPx * 72 / 96
|
|
1032
|
+
const fillImageTile = shape.fill.kind === "picture" && shape.fill.tiled === true && fillImage?.prepared ? shape.fill.tileSizePt ?? {
|
|
1033
|
+
widthPt: fillImage.prepared.widthPx * 72 / 96 * (shape.fill.tileScale?.sx ?? 1),
|
|
1034
|
+
heightPt: fillImage.prepared.heightPx * 72 / 96 * (shape.fill.tileScale?.sy ?? 1)
|
|
1033
1035
|
} : void 0;
|
|
1034
1036
|
const fillColorHex = shape.fill.kind === "solid" ? shape.fill.colorHex : fillGradient ? gradientToSolid(fillGradient) : void 0;
|
|
1035
1037
|
const stroke = buildStroke(shape.line);
|
|
@@ -1225,11 +1227,11 @@ function layoutShapeBlock(shape, options, fontResources, imageResources, content
|
|
|
1225
1227
|
* frame. So one is turned into the other rather than growing a block kind, a
|
|
1226
1228
|
* pagination arm and an emitter of its own.
|
|
1227
1229
|
*/
|
|
1228
|
-
function layoutMetafileBlock(image, pic, options, fontResources, contentWidth, maxHeight, box) {
|
|
1230
|
+
function layoutMetafileBlock(image, pic, blitted, options, fontResources, contentWidth, maxHeight, box) {
|
|
1229
1231
|
const placed = layoutImageBlock(image, void 0, contentWidth, maxHeight, box);
|
|
1230
1232
|
const widthPt = placed.widthPt;
|
|
1231
1233
|
const heightPt = placed.heightPt;
|
|
1232
|
-
const layout = rotateDrawing(metafileDrawing(pic, widthPt, heightPt, options, fontResources, image.colorChange), (image.rotation60k ?? 0) / 6e4, widthPt / 2, heightPt / 2);
|
|
1234
|
+
const layout = rotateDrawing(metafileDrawing(pic, widthPt, heightPt, options, fontResources, image.colorChange, blitted), (image.rotation60k ?? 0) / 6e4, widthPt / 2, heightPt / 2);
|
|
1233
1235
|
const pp = image.paragraphProperties;
|
|
1234
1236
|
return {
|
|
1235
1237
|
kind: "chart",
|
|
@@ -1293,7 +1295,16 @@ function rotateDrawing(layout, deg, cx, cy) {
|
|
|
1293
1295
|
y: p.y,
|
|
1294
1296
|
rotationDeg: (t.rotationDeg ?? 0) - deg
|
|
1295
1297
|
};
|
|
1296
|
-
})
|
|
1298
|
+
}),
|
|
1299
|
+
...layout.images ? { images: layout.images.map((img) => {
|
|
1300
|
+
const c = at(img.x + img.width / 2, img.y + img.height / 2);
|
|
1301
|
+
return {
|
|
1302
|
+
...img,
|
|
1303
|
+
x: c.x - img.width / 2,
|
|
1304
|
+
y: c.y - img.height / 2,
|
|
1305
|
+
rotationDeg: (img.rotationDeg ?? 0) + deg
|
|
1306
|
+
};
|
|
1307
|
+
}) } : {}
|
|
1297
1308
|
};
|
|
1298
1309
|
}
|
|
1299
1310
|
/**
|
|
@@ -1301,7 +1312,7 @@ function rotateDrawing(layout, deg, cx, cy) {
|
|
|
1301
1312
|
* `heightPt` one and turned y-up about its bottom-left corner — the frame both
|
|
1302
1313
|
* a chart block and an inline picture token are drawn in.
|
|
1303
1314
|
*/
|
|
1304
|
-
function metafileDrawing(pic, widthPt, heightPt, options, fontResources, colorChange) {
|
|
1315
|
+
function metafileDrawing(pic, widthPt, heightPt, options, fontResources, colorChange, blitted) {
|
|
1305
1316
|
const recolour = (hex) => {
|
|
1306
1317
|
if (hex === void 0 || colorChange === void 0) return hex;
|
|
1307
1318
|
if (hex.toUpperCase() !== colorChange.fromHex.toUpperCase()) return hex;
|
|
@@ -1313,8 +1324,26 @@ function metafileDrawing(pic, widthPt, heightPt, options, fontResources, colorCh
|
|
|
1313
1324
|
const mapY = (y) => heightPt - (y - pic.top) * sy;
|
|
1314
1325
|
const shapes = [];
|
|
1315
1326
|
const texts = [];
|
|
1327
|
+
const images = [];
|
|
1316
1328
|
let seq = 0;
|
|
1329
|
+
let blit = 0;
|
|
1317
1330
|
for (const prim of pic.prims) {
|
|
1331
|
+
if (prim.kind === "image") {
|
|
1332
|
+
const resourceName = blitted?.[blit++] ?? "";
|
|
1333
|
+
if (resourceName === "") {
|
|
1334
|
+
seq++;
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
images.push({
|
|
1338
|
+
seq: seq++,
|
|
1339
|
+
resourceName,
|
|
1340
|
+
x: mapX(prim.x),
|
|
1341
|
+
y: mapY(prim.y + prim.height),
|
|
1342
|
+
width: prim.width * sx,
|
|
1343
|
+
height: prim.height * sy
|
|
1344
|
+
});
|
|
1345
|
+
continue;
|
|
1346
|
+
}
|
|
1318
1347
|
if (prim.kind === "path") {
|
|
1319
1348
|
const fill = recolour(prim.fillColorHex);
|
|
1320
1349
|
const strokeHex = recolour(prim.stroke?.colorHex);
|
|
@@ -1349,7 +1378,6 @@ function metafileDrawing(pic, widthPt, heightPt, options, fontResources, colorCh
|
|
|
1349
1378
|
});
|
|
1350
1379
|
continue;
|
|
1351
1380
|
}
|
|
1352
|
-
if (prim.kind !== "text") continue;
|
|
1353
1381
|
const { variant } = options.registry.resolveByStyle(prim.bold === true, prim.italic === true);
|
|
1354
1382
|
const font = fontResources.get(variant);
|
|
1355
1383
|
if (!font) continue;
|
|
@@ -1372,7 +1400,8 @@ function metafileDrawing(pic, widthPt, heightPt, options, fontResources, colorCh
|
|
|
1372
1400
|
}
|
|
1373
1401
|
return {
|
|
1374
1402
|
shapes,
|
|
1375
|
-
texts
|
|
1403
|
+
texts,
|
|
1404
|
+
...images.length > 0 ? { images } : {}
|
|
1376
1405
|
};
|
|
1377
1406
|
}
|
|
1378
1407
|
function layoutChartBlock(block, options, fontResources, contentWidth, maxHeight, imageResources) {
|
|
@@ -1699,9 +1728,29 @@ function collectImageResources(body, headersFooters, options) {
|
|
|
1699
1728
|
if (!bytes) continue;
|
|
1700
1729
|
if (isEmf(bytes) || isWmf(bytes)) {
|
|
1701
1730
|
try {
|
|
1731
|
+
const metafile = isEmf(bytes) ? readEmf(bytes) : readWmf(bytes);
|
|
1732
|
+
const metafileImages = [];
|
|
1733
|
+
for (const prim of metafile.prims) {
|
|
1734
|
+
if (prim.kind !== "image") continue;
|
|
1735
|
+
let blitted;
|
|
1736
|
+
try {
|
|
1737
|
+
blitted = prepareImage(prim.png, { flattenAlpha });
|
|
1738
|
+
} catch {
|
|
1739
|
+
metafileImages.push("");
|
|
1740
|
+
continue;
|
|
1741
|
+
}
|
|
1742
|
+
counter++;
|
|
1743
|
+
const name = `Im${counter}`;
|
|
1744
|
+
metafileImages.push(name);
|
|
1745
|
+
out.set(`${resourceId}#${String(metafileImages.length)}`, {
|
|
1746
|
+
resourceName: name,
|
|
1747
|
+
prepared: blitted
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1702
1750
|
out.set(resourceId, {
|
|
1703
1751
|
resourceName: "",
|
|
1704
|
-
metafile
|
|
1752
|
+
metafile,
|
|
1753
|
+
...metafileImages.length > 0 ? { metafileImages } : {}
|
|
1705
1754
|
});
|
|
1706
1755
|
} catch {}
|
|
1707
1756
|
continue;
|
|
@@ -1722,7 +1771,7 @@ function collectImageResources(body, headersFooters, options) {
|
|
|
1722
1771
|
}
|
|
1723
1772
|
function chartPageItems(laid, x, bottomYUp, pageHeight, structId) {
|
|
1724
1773
|
const fig = structId !== void 0 ? { structId } : {};
|
|
1725
|
-
const ordered = laid.layout.shapes.some((sh) => sh.seq !== void 0);
|
|
1774
|
+
const ordered = laid.layout.shapes.some((sh) => sh.seq !== void 0) || (laid.layout.images?.length ?? 0) > 0;
|
|
1726
1775
|
const picture = ordered ? { pictureId: nextPictureId++ } : {};
|
|
1727
1776
|
const backdrop = [];
|
|
1728
1777
|
if (laid.background) {
|
|
@@ -1791,7 +1840,23 @@ function chartPageItems(laid, x, bottomYUp, pageHeight, structId) {
|
|
|
1791
1840
|
...picture,
|
|
1792
1841
|
seq: t.seq ?? Number.MAX_SAFE_INTEGER
|
|
1793
1842
|
}));
|
|
1794
|
-
const
|
|
1843
|
+
const blits = (laid.layout.images ?? []).map((img) => ({
|
|
1844
|
+
type: "image",
|
|
1845
|
+
x: pt(x + img.x),
|
|
1846
|
+
y: pt(pageHeight - (bottomYUp + img.y + img.height)),
|
|
1847
|
+
width: pt(img.width),
|
|
1848
|
+
height: pt(img.height),
|
|
1849
|
+
imageResourceName: img.resourceName,
|
|
1850
|
+
...img.rotationDeg ? { rotationDeg: img.rotationDeg } : {},
|
|
1851
|
+
...fig,
|
|
1852
|
+
...picture,
|
|
1853
|
+
seq: img.seq ?? 0
|
|
1854
|
+
}));
|
|
1855
|
+
const all = [
|
|
1856
|
+
...shapes,
|
|
1857
|
+
...texts,
|
|
1858
|
+
...blits
|
|
1859
|
+
];
|
|
1795
1860
|
if (ordered) all.sort((a, b) => a.seq - b.seq);
|
|
1796
1861
|
return [...backdrop, ...all.map(({ seq: _seq, ...item }) => item)];
|
|
1797
1862
|
}
|
|
@@ -2173,24 +2238,197 @@ function runFontKeyAndParsed(options, ascii, bold, italic) {
|
|
|
2173
2238
|
}
|
|
2174
2239
|
const byFamily = options.registriesByFamily;
|
|
2175
2240
|
if (byFamily && byFamily.size > 0) {
|
|
2176
|
-
|
|
2241
|
+
const named = resolveFamilyStyle(ascii);
|
|
2242
|
+
let key = named.key;
|
|
2177
2243
|
let reg = byFamily.get(key);
|
|
2178
2244
|
if (!reg) {
|
|
2179
2245
|
key = byFamily.keys().next().value;
|
|
2180
2246
|
reg = byFamily.get(key);
|
|
2181
2247
|
}
|
|
2182
|
-
const
|
|
2248
|
+
const wantBold = bold || named.bold === true;
|
|
2249
|
+
const wantItalic = italic || named.italic === true;
|
|
2250
|
+
const { variant, parsed } = reg.resolveByStyle(wantBold, wantItalic);
|
|
2183
2251
|
return {
|
|
2184
2252
|
fontKey: `${key}:${variant}`,
|
|
2185
|
-
parsed
|
|
2253
|
+
parsed,
|
|
2254
|
+
...syntheticFace(variant, wantBold, wantItalic, named.widthScale)
|
|
2186
2255
|
};
|
|
2187
2256
|
}
|
|
2188
2257
|
const { variant, parsed } = options.registry.resolveByStyle(bold, italic);
|
|
2189
2258
|
return {
|
|
2190
2259
|
fontKey: variant,
|
|
2191
|
-
parsed
|
|
2260
|
+
parsed,
|
|
2261
|
+
...syntheticFace(variant, bold, italic, resolveFamilyStyle(ascii).widthScale)
|
|
2192
2262
|
};
|
|
2193
2263
|
}
|
|
2264
|
+
/**
|
|
2265
|
+
* The face a CHARACTER falls back to when the run's own has no glyph for it.
|
|
2266
|
+
*
|
|
2267
|
+
* The curated substitutes are Latin families: Han, Kana, Hangul, Arabic, Thai
|
|
2268
|
+
* and the geometric symbols are a notdef box in every one of them, and 2145
|
|
2269
|
+
* characters of the corpus are exactly those. A face for the character's
|
|
2270
|
+
* writing system is fetched when the document holds one (see `addScriptFonts`),
|
|
2271
|
+
* and this is where a run reaches it — followed by every other family already
|
|
2272
|
+
* loaded, because a glyph one of them happens to carry is still better than a
|
|
2273
|
+
* box.
|
|
2274
|
+
*
|
|
2275
|
+
* Called from BOTH walks that need it — the glyph-subset collection and the
|
|
2276
|
+
* tokenizer — so the face a character is measured, subset and drawn with is one
|
|
2277
|
+
* decision made once.
|
|
2278
|
+
*
|
|
2279
|
+
* @param options The render options (the loaded registries).
|
|
2280
|
+
* @param cp The code point with no glyph in the run's own face.
|
|
2281
|
+
* @param bold Whether the run is bold…
|
|
2282
|
+
* @param italic …and whether it is italic.
|
|
2283
|
+
* @returns The face to draw it with, or `undefined` when nobody has it.
|
|
2284
|
+
*/
|
|
2285
|
+
function fallbackFaceKey(options, cp, bold, italic) {
|
|
2286
|
+
const byFamily = options.registriesByFamily;
|
|
2287
|
+
if (!byFamily || byFamily.size === 0) return void 0;
|
|
2288
|
+
const script = scriptForCodepoint(cp, byFamily.has("jp") ? "jp" : byFamily.has("kr") ? "kr" : "sc");
|
|
2289
|
+
const order = script ? [script] : [];
|
|
2290
|
+
for (const key of byFamily.keys()) if (key !== script) order.push(key);
|
|
2291
|
+
for (const key of order) {
|
|
2292
|
+
const reg = byFamily.get(key);
|
|
2293
|
+
if (!reg) continue;
|
|
2294
|
+
const { variant, parsed } = reg.resolveByStyle(bold, italic);
|
|
2295
|
+
if (parsed.glyphForCodepoint(cp) !== 0) return {
|
|
2296
|
+
fontKey: `${key}:${variant}`,
|
|
2297
|
+
parsed
|
|
2298
|
+
};
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* §9.2.2 — the face a request had to settle for, and what is left to draw.
|
|
2303
|
+
*
|
|
2304
|
+
* A registry may hold one face and be asked for four: `FontBytesByVariant`
|
|
2305
|
+
* requires only `regular`, so a caller who supplies a single file (or a script
|
|
2306
|
+
* fallback with no bold cut) had every heading drawn plain. What the file does
|
|
2307
|
+
* not carry, the page draws: a stroke around the glyphs for weight, a shear for
|
|
2308
|
+
* slant — the same two tricks a word processor calls faux bold and faux italic.
|
|
2309
|
+
*
|
|
2310
|
+
* @param variant The face the registry actually gave.
|
|
2311
|
+
* @param bold Whether bold was asked for.
|
|
2312
|
+
* @param italic Whether italic was.
|
|
2313
|
+
* @param widthScale The squeeze a condensed NAME asks for, when it does.
|
|
2314
|
+
* @returns `{ synthetic }` when something is missing, `{}` when nothing is.
|
|
2315
|
+
*/
|
|
2316
|
+
function syntheticFace(variant, bold, italic, widthScale) {
|
|
2317
|
+
const missingBold = bold && variant !== "bold" && variant !== "boldItalic";
|
|
2318
|
+
const missingItalic = italic && variant !== "italic" && variant !== "boldItalic";
|
|
2319
|
+
if (!missingBold && !missingItalic && widthScale === void 0) return {};
|
|
2320
|
+
return { synthetic: {
|
|
2321
|
+
...missingBold ? { bold: true } : {},
|
|
2322
|
+
...missingItalic ? { italic: true } : {},
|
|
2323
|
+
...widthScale !== void 0 ? { widthScale } : {}
|
|
2324
|
+
} };
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* `text` cut into the stretches ONE face draws — the whole string as a single
|
|
2328
|
+
* piece when the run's own face covers it, which is nearly always.
|
|
2329
|
+
*
|
|
2330
|
+
* @param plan The run being tokenized.
|
|
2331
|
+
* @param text The stretch of it to cut.
|
|
2332
|
+
*/
|
|
2333
|
+
function splitByFace(plan, text) {
|
|
2334
|
+
const first = faceOf(plan, text.codePointAt(0) ?? 0);
|
|
2335
|
+
if (!plan.faceFor || plan.faceFor.size === 0) return [{
|
|
2336
|
+
text,
|
|
2337
|
+
face: first
|
|
2338
|
+
}];
|
|
2339
|
+
const out = [];
|
|
2340
|
+
let buf = "";
|
|
2341
|
+
let face = first;
|
|
2342
|
+
for (const ch of text) {
|
|
2343
|
+
const next = faceOf(plan, ch.codePointAt(0));
|
|
2344
|
+
if (buf !== "" && next.font !== face.font) {
|
|
2345
|
+
out.push({
|
|
2346
|
+
text: buf,
|
|
2347
|
+
face
|
|
2348
|
+
});
|
|
2349
|
+
buf = "";
|
|
2350
|
+
}
|
|
2351
|
+
face = next;
|
|
2352
|
+
buf += ch;
|
|
2353
|
+
}
|
|
2354
|
+
if (buf !== "") out.push({
|
|
2355
|
+
text: buf,
|
|
2356
|
+
face
|
|
2357
|
+
});
|
|
2358
|
+
return out;
|
|
2359
|
+
}
|
|
2360
|
+
/**
|
|
2361
|
+
* The face a character of a run is drawn with — its own, unless the run carries
|
|
2362
|
+
* a fallback for that code point (see {@link facesForRun}).
|
|
2363
|
+
*/
|
|
2364
|
+
function faceOf(plan, cp) {
|
|
2365
|
+
return plan.faceFor?.get(cp) ?? {
|
|
2366
|
+
font: plan.font,
|
|
2367
|
+
...plan.synthetic ? { synthetic: plan.synthetic } : {}
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
/**
|
|
2371
|
+
* `text` cut into the stretches ONE face draws, by the same decision the
|
|
2372
|
+
* tokenizer makes — the whole string as a single span when the run's own face
|
|
2373
|
+
* covers it, which is nearly always.
|
|
2374
|
+
*
|
|
2375
|
+
* @param options The render options (the loaded registries).
|
|
2376
|
+
* @param primary The run's own face.
|
|
2377
|
+
* @param resolved Its resolved properties (weight and slant).
|
|
2378
|
+
* @param text The run's text.
|
|
2379
|
+
*/
|
|
2380
|
+
function faceSpans(options, primary, resolved, text) {
|
|
2381
|
+
const out = [];
|
|
2382
|
+
let cur = primary;
|
|
2383
|
+
let buf = "";
|
|
2384
|
+
for (const ch of text) {
|
|
2385
|
+
const cp = ch.codePointAt(0);
|
|
2386
|
+
const face = primary.parsed.glyphForCodepoint(cp) !== 0 ? primary : fallbackFaceKey(options, cp, resolved.bold, resolved.italic) ?? primary;
|
|
2387
|
+
if (buf !== "" && face.fontKey !== cur.fontKey) {
|
|
2388
|
+
out.push({
|
|
2389
|
+
...cur,
|
|
2390
|
+
text: buf
|
|
2391
|
+
});
|
|
2392
|
+
buf = "";
|
|
2393
|
+
}
|
|
2394
|
+
cur = face;
|
|
2395
|
+
buf += ch;
|
|
2396
|
+
}
|
|
2397
|
+
if (buf !== "") out.push({
|
|
2398
|
+
...cur,
|
|
2399
|
+
text: buf
|
|
2400
|
+
});
|
|
2401
|
+
return out;
|
|
2402
|
+
}
|
|
2403
|
+
/**
|
|
2404
|
+
* The face for every character of `text` the run's own cannot draw.
|
|
2405
|
+
*
|
|
2406
|
+
* @param options The render options (the loaded registries).
|
|
2407
|
+
* @param fontResources The faces the document embeds, by key.
|
|
2408
|
+
* @param primary The run's own face.
|
|
2409
|
+
* @param resolved Its resolved properties (weight and slant).
|
|
2410
|
+
* @param text The run's text.
|
|
2411
|
+
* @returns A map from code point to face, or `undefined` when the run's own
|
|
2412
|
+
* face draws all of it.
|
|
2413
|
+
*/
|
|
2414
|
+
function facesForRun(options, fontResources, primary, resolved, text) {
|
|
2415
|
+
let out;
|
|
2416
|
+
for (const ch of text) {
|
|
2417
|
+
const cp = ch.codePointAt(0);
|
|
2418
|
+
if (out?.has(cp) === true || primary.glyphForCodepoint(cp) !== 0) continue;
|
|
2419
|
+
const fallback = fallbackFaceKey(options, cp, resolved.bold, resolved.italic);
|
|
2420
|
+
if (!fallback) continue;
|
|
2421
|
+
const font = fontResources.get(fallback.fontKey);
|
|
2422
|
+
if (!font) continue;
|
|
2423
|
+
out ??= /* @__PURE__ */ new Map();
|
|
2424
|
+
const { variant } = { variant: fallback.fontKey.split(":")[1] ?? "" };
|
|
2425
|
+
out.set(cp, {
|
|
2426
|
+
font,
|
|
2427
|
+
...syntheticFace(variant === "bold" || variant === "boldItalic" || variant === "italic" ? variant : "regular", resolved.bold, resolved.italic)
|
|
2428
|
+
});
|
|
2429
|
+
}
|
|
2430
|
+
return out;
|
|
2431
|
+
}
|
|
2194
2432
|
function lookupFont(resources, fontKey) {
|
|
2195
2433
|
return resources.get(fontKey) ?? resources.values().next().value;
|
|
2196
2434
|
}
|
|
@@ -2207,8 +2445,22 @@ function collectFontResources(body, headersFooters, options, imageResources) {
|
|
|
2207
2445
|
};
|
|
2208
2446
|
used.set(fontKey, bucket);
|
|
2209
2447
|
}
|
|
2210
|
-
const
|
|
2211
|
-
for (const
|
|
2448
|
+
const text = run.listMarker === true ? markerText(run.text, parsed) : run.text;
|
|
2449
|
+
for (const span of faceSpans(options, {
|
|
2450
|
+
fontKey,
|
|
2451
|
+
parsed
|
|
2452
|
+
}, resolved, text)) {
|
|
2453
|
+
let sink = used.get(span.fontKey);
|
|
2454
|
+
if (!sink) {
|
|
2455
|
+
sink = {
|
|
2456
|
+
parsed: span.parsed,
|
|
2457
|
+
gids: /* @__PURE__ */ new Set()
|
|
2458
|
+
};
|
|
2459
|
+
used.set(span.fontKey, sink);
|
|
2460
|
+
}
|
|
2461
|
+
const shaped = shapeText(span.text, span.parsed.glyphForCodepoint, span.parsed.advanceWidths, span.parsed.ligatures, span.parsed.kerning, span.parsed.joiningForms);
|
|
2462
|
+
for (const g of shaped.gids) sink.gids.add(g);
|
|
2463
|
+
}
|
|
2212
2464
|
if (run.text.includes(" ")) for (const stop of resolveParagraphProperties(para.properties, options.styles).tabs) {
|
|
2213
2465
|
const ch = stop.leader === void 0 ? void 0 : TAB_LEADER_CHARS.get(stop.leader);
|
|
2214
2466
|
if (ch !== void 0) bucket.gids.add(parsed.glyphForCodepoint(ch.codePointAt(0)));
|
|
@@ -2578,7 +2830,7 @@ function tokenizeParagraph(paragraph, options, fontResources, imageResources, co
|
|
|
2578
2830
|
imageWidthPt: widthPt,
|
|
2579
2831
|
imageHeightPt: heightPt,
|
|
2580
2832
|
imageResourceName: res?.resourceName ?? "",
|
|
2581
|
-
...res?.metafile ? { imageMetafile: metafileDrawing(res.metafile, drawBox?.widthPt ?? widthPt, drawBox?.heightPt ?? heightPt, options, fontResources) } : {},
|
|
2833
|
+
...res?.metafile ? { imageMetafile: metafileDrawing(res.metafile, drawBox?.widthPt ?? widthPt, drawBox?.heightPt ?? heightPt, options, fontResources, void 0, res.metafileImages) } : {},
|
|
2582
2834
|
...run.inlineImage.outline ? { imageOutline: run.inlineImage.outline } : {},
|
|
2583
2835
|
...run.inlineImage.shadow ? { imageShadow: run.inlineImage.shadow } : {},
|
|
2584
2836
|
...run.inlineImage.wash ? { imageWash: run.inlineImage.wash } : {},
|
|
@@ -2618,12 +2870,16 @@ function tokenizeParagraph(paragraph, options, fontResources, imageResources, co
|
|
|
2618
2870
|
};
|
|
2619
2871
|
}
|
|
2620
2872
|
const resolvedRun = resolveRunProperties(run.properties, paragraph.properties, options.styles);
|
|
2621
|
-
const { fontKey } = runFontKeyAndParsed(options, resolvedRun.fontFamily.ascii, resolvedRun.bold, resolvedRun.italic);
|
|
2873
|
+
const { fontKey, synthetic } = runFontKeyAndParsed(options, resolvedRun.fontFamily.ascii, resolvedRun.bold, resolvedRun.italic);
|
|
2622
2874
|
const script = SCRIPT_OFFSET[resolvedRun.verticalAlign] ?? 0;
|
|
2875
|
+
const own = lookupFont(fontResources, fontKey);
|
|
2876
|
+
const faceFor = facesForRun(options, fontResources, own.parsed, resolvedRun, run.text);
|
|
2623
2877
|
return {
|
|
2624
2878
|
run,
|
|
2625
2879
|
resolvedRun,
|
|
2626
|
-
font:
|
|
2880
|
+
font: own,
|
|
2881
|
+
...faceFor ? { faceFor } : {},
|
|
2882
|
+
...synthetic ? { synthetic } : {},
|
|
2627
2883
|
fontSizePt: script === 0 ? resolvedRun.fontSizePt : resolvedRun.fontSizePt * SCRIPT_SCALE,
|
|
2628
2884
|
...script === 0 ? {} : { risePt: resolvedRun.fontSizePt * script },
|
|
2629
2885
|
isImage: false,
|
|
@@ -2690,8 +2946,8 @@ function tokenizePlansLtr(plans) {
|
|
|
2690
2946
|
continue;
|
|
2691
2947
|
}
|
|
2692
2948
|
const highlight = (plan.run.commentRangeRefs?.length ?? 0) > 0;
|
|
2693
|
-
for (const t of tokenizeText(plan.run.text)) {
|
|
2694
|
-
const text = plan.run.listMarker === true ? markerText(
|
|
2949
|
+
for (const t of tokenizeText(plan.run.text)) for (const piece of splitByFace(plan, t.text)) {
|
|
2950
|
+
const text = plan.run.listMarker === true ? markerText(piece.text, plan.font.parsed) : piece.text;
|
|
2695
2951
|
tokens.push({
|
|
2696
2952
|
kind: "text",
|
|
2697
2953
|
text,
|
|
@@ -2704,10 +2960,11 @@ function tokenizePlansLtr(plans) {
|
|
|
2704
2960
|
...plan.run.columnBreak ? { columnBreak: true } : {},
|
|
2705
2961
|
...highlight ? { highlight: true } : {},
|
|
2706
2962
|
resolvedRun: plan.resolvedRun,
|
|
2707
|
-
font:
|
|
2963
|
+
font: piece.face.font,
|
|
2964
|
+
...piece.face.synthetic ? { synthetic: piece.face.synthetic } : {},
|
|
2708
2965
|
fontSizePt: plan.fontSizePt,
|
|
2709
2966
|
...plan.risePt !== void 0 ? { risePt: plan.risePt } : {},
|
|
2710
|
-
widthPt: measureRunText(plan, text),
|
|
2967
|
+
widthPt: measureRunText(plan, text, piece.face),
|
|
2711
2968
|
bidiLevel: 0
|
|
2712
2969
|
});
|
|
2713
2970
|
}
|
|
@@ -2747,8 +3004,12 @@ function markerText(text, parsed) {
|
|
|
2747
3004
|
* @param text The token's text.
|
|
2748
3005
|
* @returns The advance width in points.
|
|
2749
3006
|
*/
|
|
2750
|
-
function measureRunText(plan, text) {
|
|
2751
|
-
const
|
|
3007
|
+
function measureRunText(plan, text, face) {
|
|
3008
|
+
const drawn = face ?? {
|
|
3009
|
+
font: plan.font,
|
|
3010
|
+
...plan.synthetic ? { synthetic: plan.synthetic } : {}
|
|
3011
|
+
};
|
|
3012
|
+
const base = drawn.font.measure.textWidthPt(text, plan.fontSizePt) * (drawn.synthetic?.widthScale ?? 1);
|
|
2752
3013
|
const extra = plan.resolvedRun.letterSpacingPt;
|
|
2753
3014
|
return extra === void 0 || extra === 0 ? base : base + extra * [...text].length;
|
|
2754
3015
|
}
|
|
@@ -2795,6 +3056,7 @@ function tokenizePlansBidi(plans, realLevels) {
|
|
|
2795
3056
|
let bufStart = 0;
|
|
2796
3057
|
let curSpace = false;
|
|
2797
3058
|
let curLevel = -1;
|
|
3059
|
+
let curFace = { font: plan.font };
|
|
2798
3060
|
const flush = (endExclusive) => {
|
|
2799
3061
|
if (endExclusive <= bufStart) return;
|
|
2800
3062
|
const raw = chars.slice(bufStart, endExclusive).join("");
|
|
@@ -2810,10 +3072,11 @@ function tokenizePlansBidi(plans, realLevels) {
|
|
|
2810
3072
|
...plan.run.columnBreak ? { columnBreak: true } : {},
|
|
2811
3073
|
...(plan.run.commentRangeRefs?.length ?? 0) > 0 ? { highlight: true } : {},
|
|
2812
3074
|
resolvedRun: plan.resolvedRun,
|
|
2813
|
-
font:
|
|
3075
|
+
font: curFace.font,
|
|
3076
|
+
...curFace.synthetic ? { synthetic: curFace.synthetic } : {},
|
|
2814
3077
|
fontSizePt: plan.fontSizePt,
|
|
2815
3078
|
...plan.risePt !== void 0 ? { risePt: plan.risePt } : {},
|
|
2816
|
-
widthPt: measureRunText(plan, text),
|
|
3079
|
+
widthPt: measureRunText(plan, text, curFace),
|
|
2817
3080
|
bidiLevel: curLevel
|
|
2818
3081
|
});
|
|
2819
3082
|
};
|
|
@@ -2821,14 +3084,17 @@ function tokenizePlansBidi(plans, realLevels) {
|
|
|
2821
3084
|
const ch = chars[c];
|
|
2822
3085
|
const isSpace = /\s/.test(ch);
|
|
2823
3086
|
const level = realLevels[realIdx] ?? 0;
|
|
3087
|
+
const face = faceOf(plan, ch.codePointAt(0));
|
|
2824
3088
|
if (c === 0) {
|
|
2825
3089
|
curSpace = isSpace;
|
|
2826
3090
|
curLevel = level;
|
|
2827
|
-
|
|
3091
|
+
curFace = face;
|
|
3092
|
+
} else if (isSpace !== curSpace || level !== curLevel || face.font !== curFace.font) {
|
|
2828
3093
|
flush(c);
|
|
2829
3094
|
bufStart = c;
|
|
2830
3095
|
curSpace = isSpace;
|
|
2831
3096
|
curLevel = level;
|
|
3097
|
+
curFace = face;
|
|
2832
3098
|
}
|
|
2833
3099
|
realIdx++;
|
|
2834
3100
|
}
|
|
@@ -3656,10 +3922,10 @@ function measureSingleLine(paragraph, options, fontResources) {
|
|
|
3656
3922
|
let total = 0;
|
|
3657
3923
|
for (const run of paragraph.runs) {
|
|
3658
3924
|
const resolved = resolveRunProperties(run.properties, paragraph.properties, options.styles);
|
|
3659
|
-
const { fontKey } = runFontKeyAndParsed(options, resolved.fontFamily.ascii, resolved.bold, resolved.italic);
|
|
3925
|
+
const { fontKey, synthetic } = runFontKeyAndParsed(options, resolved.fontFamily.ascii, resolved.bold, resolved.italic);
|
|
3660
3926
|
const font = lookupFont(fontResources, fontKey);
|
|
3661
3927
|
const fontSizePt = resolved.fontSizePt;
|
|
3662
|
-
total += font.measure.textWidthPt(run.text, fontSizePt);
|
|
3928
|
+
total += font.measure.textWidthPt(run.text, fontSizePt) * (synthetic?.widthScale ?? 1);
|
|
3663
3929
|
}
|
|
3664
3930
|
return total;
|
|
3665
3931
|
}
|
|
@@ -621,6 +621,7 @@ var BORDER_DASHES = new Map([
|
|
|
621
621
|
2.5
|
|
622
622
|
]]
|
|
623
623
|
]);
|
|
624
|
+
var FAUX_ITALIC_SHEAR = .2126;
|
|
624
625
|
/** The PDF dash array for a border style; an empty string means a solid rule. */
|
|
625
626
|
function dashPatternFor(style) {
|
|
626
627
|
const pattern = style !== void 0 ? BORDER_DASHES.get(style) : void 0;
|
|
@@ -642,6 +643,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
642
643
|
let lastTc = 0;
|
|
643
644
|
let lastSize = -1;
|
|
644
645
|
let lastColor = "";
|
|
646
|
+
let lastFauxWidth = 0;
|
|
647
|
+
let lastTz = 100;
|
|
645
648
|
const switchFontIfNeeded = (tok) => {
|
|
646
649
|
const fontKey = tok.font.resourceName;
|
|
647
650
|
if (fontKey !== lastFont || tok.fontSizePt !== lastSize) {
|
|
@@ -649,6 +652,16 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
649
652
|
lastFont = fontKey;
|
|
650
653
|
lastSize = tok.fontSizePt;
|
|
651
654
|
}
|
|
655
|
+
const fauxWidth = tok.synthetic?.bold === true ? tok.fontSizePt * .03 : 0;
|
|
656
|
+
if (fauxWidth !== lastFauxWidth) {
|
|
657
|
+
out.push(fauxWidth > 0 ? `2 Tr ${formatNumber(fauxWidth)} w` : "0 Tr");
|
|
658
|
+
lastFauxWidth = fauxWidth;
|
|
659
|
+
}
|
|
660
|
+
const tz = Math.round((tok.synthetic?.widthScale ?? 1) * 100);
|
|
661
|
+
if (tz !== lastTz) {
|
|
662
|
+
out.push(`${formatNumber(tz)} Tz`);
|
|
663
|
+
lastTz = tz;
|
|
664
|
+
}
|
|
652
665
|
const tc = tok.resolvedRun.letterSpacingPt ?? 0;
|
|
653
666
|
if (tc !== lastTc) {
|
|
654
667
|
out.push(`${formatNumber(tc)} Tc`);
|
|
@@ -670,6 +683,12 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
670
683
|
const b = tok.drawBox;
|
|
671
684
|
const ox = x + (b?.dxPt ?? 0);
|
|
672
685
|
const oy = baselineY + (b?.dyPt ?? 0);
|
|
686
|
+
for (const img of meta.images ?? []) {
|
|
687
|
+
if (img.resourceName === "") continue;
|
|
688
|
+
out.push("q");
|
|
689
|
+
out.push(...placeImage(ox + img.x, oy + img.y, img.width, img.height, void 0, img.rotationDeg));
|
|
690
|
+
out.push(`/${img.resourceName} Do`, "Q");
|
|
691
|
+
}
|
|
673
692
|
for (const sh of meta.shapes) for (const op of emitVectorShape({
|
|
674
693
|
...sh,
|
|
675
694
|
transform: [
|
|
@@ -693,6 +712,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
693
712
|
out.push("ET");
|
|
694
713
|
}
|
|
695
714
|
lastFont = "";
|
|
715
|
+
lastFauxWidth = 0;
|
|
716
|
+
lastTz = 100;
|
|
696
717
|
lastSize = -1;
|
|
697
718
|
lastColor = "";
|
|
698
719
|
return;
|
|
@@ -739,6 +760,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
739
760
|
out.push("Q");
|
|
740
761
|
}
|
|
741
762
|
lastFont = "";
|
|
763
|
+
lastFauxWidth = 0;
|
|
764
|
+
lastTz = 100;
|
|
742
765
|
lastSize = -1;
|
|
743
766
|
lastColor = "";
|
|
744
767
|
lastTc = 0;
|
|
@@ -771,6 +794,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
771
794
|
out.push("f");
|
|
772
795
|
out.push("Q");
|
|
773
796
|
lastFont = "";
|
|
797
|
+
lastFauxWidth = 0;
|
|
798
|
+
lastTz = 100;
|
|
774
799
|
lastSize = -1;
|
|
775
800
|
lastColor = "";
|
|
776
801
|
} else {
|
|
@@ -796,6 +821,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
796
821
|
};
|
|
797
822
|
for (const op of emitVectorShape(shape)) out.push(op);
|
|
798
823
|
lastFont = "";
|
|
824
|
+
lastFauxWidth = 0;
|
|
825
|
+
lastTz = 100;
|
|
799
826
|
lastSize = -1;
|
|
800
827
|
lastColor = "";
|
|
801
828
|
}
|
|
@@ -813,6 +840,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
813
840
|
out.push("q");
|
|
814
841
|
out.push(`${formatNumber(clip.x)} ${formatNumber(H - clip.y - clip.height)} ${formatNumber(clip.width)} ${formatNumber(clip.height)} re W n`);
|
|
815
842
|
lastFont = "";
|
|
843
|
+
lastFauxWidth = 0;
|
|
844
|
+
lastTz = 100;
|
|
816
845
|
lastSize = -1;
|
|
817
846
|
lastColor = "";
|
|
818
847
|
lastTc = 0;
|
|
@@ -825,6 +854,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
825
854
|
}
|
|
826
855
|
out.push("Q");
|
|
827
856
|
lastFont = "";
|
|
857
|
+
lastFauxWidth = 0;
|
|
858
|
+
lastTz = 100;
|
|
828
859
|
lastSize = -1;
|
|
829
860
|
lastColor = "";
|
|
830
861
|
lastTc = 0;
|
|
@@ -977,6 +1008,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
977
1008
|
out.push("Q");
|
|
978
1009
|
}
|
|
979
1010
|
const hasRise = line.tokens.some((t) => t.kind === "text" && t.risePt !== void 0);
|
|
1011
|
+
const hasFauxItalic = line.tokens.some((t) => t.kind === "text" && t.synthetic?.italic === true);
|
|
980
1012
|
if (rotationDeg !== 0 && !hasImageToken && !hasMathToken) {
|
|
981
1013
|
if (!inBT) {
|
|
982
1014
|
out.push("BT");
|
|
@@ -991,7 +1023,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
991
1023
|
switchFontIfNeeded(tok);
|
|
992
1024
|
out.push(tok.font.measure.showText(tok.text));
|
|
993
1025
|
}
|
|
994
|
-
} else if (extraPerSpace !== 0 || hasImageToken || hasMathToken || hasRtl || hasRise || hasTab) {
|
|
1026
|
+
} else if (extraPerSpace !== 0 || hasImageToken || hasMathToken || hasRtl || hasRise || hasFauxItalic || hasTab) {
|
|
995
1027
|
const order = hasRtl ? lineVisualOrder(line) : line.tokens.map((_, i) => i);
|
|
996
1028
|
let x = originX;
|
|
997
1029
|
for (const ti of order) {
|
|
@@ -1013,7 +1045,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
1013
1045
|
inBT = true;
|
|
1014
1046
|
}
|
|
1015
1047
|
switchFontIfNeeded(tok);
|
|
1016
|
-
|
|
1048
|
+
const slant = tok.synthetic?.italic === true ? FAUX_ITALIC_SHEAR : 0;
|
|
1049
|
+
out.push(`1 0 ${formatNumber(slant)} 1 ${formatNumber(x)} ${formatNumber(baselineY + (tok.risePt ?? 0))} Tm`);
|
|
1017
1050
|
out.push(showToken(tok));
|
|
1018
1051
|
const tokenX0 = x;
|
|
1019
1052
|
x += tok.widthPt;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PDF_NULL, PdfHexString, PdfName, PdfStream } from "../pdf/objects.js";
|
|
2
2
|
import { lzwDecodeMsb } from "../core/lzw.js";
|
|
3
|
+
import { encodePng } from "../core/png-encode.js";
|
|
3
4
|
import { reversePredictor } from "./predictor.js";
|
|
4
5
|
import { decodeCcitt } from "./ccitt.js";
|
|
5
|
-
import { encodePng } from "./png-encode.js";
|
|
6
6
|
import { unzlibSync } from "fflate";
|
|
7
7
|
//#region src/pdf-reader/image-decode.ts
|
|
8
8
|
var MAX_PIXELS = 4e7;
|