pdf-parser.js 4.8.10 → 4.8.12
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/annotations.cjs +16 -16
- package/dist/annotations.js +16 -16
- package/dist/cff-probe.cjs +1 -1
- package/dist/cff-probe.js +1 -1
- package/dist/crypto/rc4.cjs +4 -5
- package/dist/crypto/rc4.js +4 -5
- package/dist/crypto/sha2.cjs +10 -10
- package/dist/crypto/sha2.js +10 -10
- package/dist/encrypt-write.cjs +0 -1
- package/dist/encrypt-write.js +0 -1
- package/dist/font-style.cjs +9 -11
- package/dist/font-style.js +9 -11
- package/dist/glyf-contours-OSdG6Edr.d.ts +13 -0
- package/dist/glyf-contours-zRQbj-Yp.d.cts +13 -0
- package/dist/glyf-contours.d.cts +1 -12
- package/dist/glyf-contours.d.ts +1 -12
- package/dist/glyf-nXC-IDRW.d.cts +33 -0
- package/dist/glyf-vMGtP1pb.d.ts +33 -0
- package/dist/glyf.d.cts +1 -32
- package/dist/glyf.d.ts +1 -32
- package/dist/image/jp2-boxes.cjs +12 -15
- package/dist/image/jp2-boxes.js +12 -15
- package/dist/image/jpeg2000-codestream.cjs +13 -12
- package/dist/image/jpeg2000-codestream.d.cts +11 -1
- package/dist/image/jpeg2000-codestream.d.ts +11 -1
- package/dist/image/jpeg2000-codestream.js +13 -13
- package/dist/image/jpeg2000-dwt.cjs +23 -17
- package/dist/image/jpeg2000-dwt.d.cts +13 -1
- package/dist/image/jpeg2000-dwt.d.ts +13 -1
- package/dist/image/jpeg2000-dwt.js +18 -18
- package/dist/math-content-write.cjs +3 -6
- package/dist/math-content-write.js +3 -6
- package/dist/math-stretch.cjs +0 -1
- package/dist/math-stretch.js +0 -1
- package/dist/navigation.cjs +0 -8
- package/dist/navigation.js +0 -8
- package/dist/raster.cjs +34 -41
- package/dist/raster.d.cts +21 -1
- package/dist/raster.d.ts +21 -1
- package/dist/raster.js +32 -42
- package/dist/read.cjs +1 -1
- package/dist/read.js +1 -1
- package/dist/serialize.cjs +1 -5
- package/dist/serialize.js +1 -5
- package/dist/write.cjs +1 -5
- package/dist/write.js +2 -6
- package/dist/xmp.cjs +3 -3
- package/dist/xmp.js +3 -3
- package/package.json +1 -1
package/dist/raster.cjs
CHANGED
|
@@ -17,7 +17,6 @@ const require_read = require("./read.cjs");
|
|
|
17
17
|
const require_glyf = require("./glyf.cjs");
|
|
18
18
|
const require_glyf_contours = require("./glyf-contours.cjs");
|
|
19
19
|
//#region src/raster.ts
|
|
20
|
-
const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
21
20
|
function regionPixels(extentPt, scale) {
|
|
22
21
|
return Math.max(1, Math.ceil(extentPt * scale - 1e-9));
|
|
23
22
|
}
|
|
@@ -46,7 +45,7 @@ function renderPdfPage(pdfBytes, pageIndex, options, rasteriser) {
|
|
|
46
45
|
cropBox = mediaBox;
|
|
47
46
|
}
|
|
48
47
|
const rotation = require_read.normalizeRotation(require_objects.asNumber(require_objects.dictGet(page, "Rotate")));
|
|
49
|
-
const rotationResult = require_read.pageRotationTransform(rotation,
|
|
48
|
+
const rotationResult = require_read.pageRotationTransform(rotation, 0, 0);
|
|
50
49
|
const visibleRect = rotatedRectBounds(cropBox, rotationResult.matrix);
|
|
51
50
|
const pageWidthPt = visibleRect.maxX - visibleRect.minX;
|
|
52
51
|
const pageHeightPt = visibleRect.maxY - visibleRect.minY;
|
|
@@ -483,7 +482,7 @@ function openEmbeddedProgram(descriptorOwner, resolver) {
|
|
|
483
482
|
const stream = resolver.resolve(require_objects.dictGet(descriptor, key));
|
|
484
483
|
if (stream?.kind !== "stream") continue;
|
|
485
484
|
const bytes = require_filters.decodeStream(stream.raw, stream.dict, require_diagnostics.NOOP_DIAGNOSTIC_SINK).bytes;
|
|
486
|
-
if (bytes
|
|
485
|
+
if (bytes[0] === 1 && bytes[1] === 0 && bytes[2] === 4) return { kind: "cff" };
|
|
487
486
|
const sfnt = require_sfnt.parseSfnt(bytes);
|
|
488
487
|
if (sfnt === void 0) continue;
|
|
489
488
|
if (sfnt.tables.has("CFF ")) return { kind: "cff" };
|
|
@@ -499,10 +498,8 @@ function openEmbeddedProgram(descriptorOwner, resolver) {
|
|
|
499
498
|
kind: "glyf",
|
|
500
499
|
sfnt,
|
|
501
500
|
face: {
|
|
502
|
-
composite: false,
|
|
503
501
|
glyf,
|
|
504
|
-
unitsPerEm: head.unitsPerEm
|
|
505
|
-
glyphIdOf: () => void 0
|
|
502
|
+
unitsPerEm: head.unitsPerEm
|
|
506
503
|
}
|
|
507
504
|
};
|
|
508
505
|
}
|
|
@@ -574,17 +571,15 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
|
|
|
574
571
|
const entries = [];
|
|
575
572
|
for (let i = 0; i + 1 < decodedBytes.length; i += 2) entries.push(decodedBytes[i] << 8 | decodedBytes[i + 1]);
|
|
576
573
|
return {
|
|
577
|
-
composite: true,
|
|
578
574
|
glyf: program.face.glyf,
|
|
579
575
|
unitsPerEm: program.face.unitsPerEm,
|
|
580
576
|
glyphIdOf: (codes, offset) => {
|
|
581
577
|
const cid = codes[offset] << 8 | codes[offset + 1];
|
|
582
|
-
return
|
|
578
|
+
return entries[cid];
|
|
583
579
|
}
|
|
584
580
|
};
|
|
585
581
|
}
|
|
586
582
|
return {
|
|
587
|
-
composite: true,
|
|
588
583
|
glyf: program.face.glyf,
|
|
589
584
|
unitsPerEm: program.face.unitsPerEm,
|
|
590
585
|
glyphIdOf: (codes, offset) => codes[offset] << 8 | codes[offset + 1]
|
|
@@ -606,7 +601,6 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
|
|
|
606
601
|
return;
|
|
607
602
|
}
|
|
608
603
|
return {
|
|
609
|
-
composite: false,
|
|
610
604
|
glyf: program.face.glyf,
|
|
611
605
|
unitsPerEm: program.face.unitsPerEm,
|
|
612
606
|
glyphIdOf: (codes, offset) => {
|
|
@@ -624,14 +618,13 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
|
|
|
624
618
|
function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDeviceMatrix, rasteriser, sink) {
|
|
625
619
|
const face = resolveTextOutlineFace(item.fontResourceName, item.resources, resolver, fontResolver, outlineFaces, sink);
|
|
626
620
|
if (face === void 0) return;
|
|
627
|
-
const composite = face.composite;
|
|
628
621
|
const placements = [];
|
|
629
622
|
let offset = 0;
|
|
630
623
|
let cumulative = 0;
|
|
631
624
|
while (offset < item.codes.length) {
|
|
632
625
|
const advance = fontResolver.metrics.glyphAdvance(item.fontResourceName, item.resources, item.codes, offset);
|
|
633
|
-
const widthPer1000 = advance
|
|
634
|
-
const byteLength = advance
|
|
626
|
+
const widthPer1000 = advance.widthPer1000;
|
|
627
|
+
const byteLength = advance.byteLengthConsumed;
|
|
635
628
|
placements.push({
|
|
636
629
|
glyphId: face.glyphIdOf(item.codes, offset),
|
|
637
630
|
advance: cumulative
|
|
@@ -660,20 +653,23 @@ function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDevi
|
|
|
660
653
|
for (const placement of placements) {
|
|
661
654
|
if (placement.glyphId === void 0) continue;
|
|
662
655
|
const outline = require_glyf_contours.decodeGlyphOutline(face.glyf, placement.glyphId);
|
|
663
|
-
if (outline === void 0
|
|
656
|
+
if (outline === void 0) continue;
|
|
664
657
|
const trm = require_matrix.multiplyMatrices(require_matrix.translationMatrix(placement.advance * correction, 0), item.startMatrix);
|
|
665
|
-
|
|
666
|
-
if (subpaths.length === 0) continue;
|
|
667
|
-
rasteriser.draw({
|
|
668
|
-
kind: "path",
|
|
669
|
-
subpaths,
|
|
670
|
-
fill: {
|
|
671
|
-
color: item.color,
|
|
672
|
-
fillRule: "nonzero"
|
|
673
|
-
}
|
|
674
|
-
});
|
|
658
|
+
drawGlyphOutline(outline, require_matrix.multiplyMatrices(glyphScale, require_matrix.multiplyMatrices(trm, interpretToDeviceMatrix)), item.color, rasteriser);
|
|
675
659
|
}
|
|
676
660
|
}
|
|
661
|
+
function drawGlyphOutline(outline, glyphMatrix, color, rasteriser) {
|
|
662
|
+
const subpaths = glyphOutlineSubpaths(outline, glyphMatrix);
|
|
663
|
+
if (subpaths.length === 0) return;
|
|
664
|
+
rasteriser.draw({
|
|
665
|
+
kind: "path",
|
|
666
|
+
subpaths,
|
|
667
|
+
fill: {
|
|
668
|
+
color,
|
|
669
|
+
fillRule: "nonzero"
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
}
|
|
677
673
|
function glyphOutlineSubpaths(outline, matrix) {
|
|
678
674
|
const subpaths = [];
|
|
679
675
|
for (const contour of outline.contours) {
|
|
@@ -684,8 +680,9 @@ function glyphOutlineSubpaths(outline, matrix) {
|
|
|
684
680
|
y: point.y,
|
|
685
681
|
onCurve: point.onCurve
|
|
686
682
|
}));
|
|
687
|
-
const
|
|
688
|
-
|
|
683
|
+
const hasLeadingOnCurvePoint = firstOn >= 0;
|
|
684
|
+
const ordered = hasLeadingOnCurvePoint ? [...contourPoints.slice(firstOn), ...contourPoints.slice(0, firstOn)] : contourPoints;
|
|
685
|
+
let current = hasLeadingOnCurvePoint ? {
|
|
689
686
|
x: contourPoints[firstOn].x,
|
|
690
687
|
y: contourPoints[firstOn].y
|
|
691
688
|
} : {
|
|
@@ -734,27 +731,20 @@ function glyphOutlineSubpaths(outline, matrix) {
|
|
|
734
731
|
pendingOffCurve = point;
|
|
735
732
|
}
|
|
736
733
|
if (pendingOffCurve !== void 0) emitQuad(current, pendingOffCurve, start);
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
});
|
|
745
|
-
}
|
|
734
|
+
const startPx = require_matrix.applyMatrix(matrix, start);
|
|
735
|
+
subpaths.push({
|
|
736
|
+
startXPx: startPx.x,
|
|
737
|
+
startYPx: startPx.y,
|
|
738
|
+
segments,
|
|
739
|
+
closed: true
|
|
740
|
+
});
|
|
746
741
|
}
|
|
747
742
|
return subpaths;
|
|
748
743
|
}
|
|
749
|
-
const PDF_HEADER_BYTES = new TextEncoder().encode("%PDF-");
|
|
750
744
|
const HEADER_SEARCH_WINDOW = 1024;
|
|
751
745
|
function hasPdfHeader(bytes) {
|
|
752
746
|
const window = bytes.subarray(0, Math.min(HEADER_SEARCH_WINDOW, bytes.length));
|
|
753
|
-
|
|
754
|
-
for (let j = 0; j < PDF_HEADER_BYTES.length; j++) if (window[i + j] !== PDF_HEADER_BYTES[j]) continue outer;
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
return false;
|
|
747
|
+
return new TextDecoder("latin1").decode(window).includes("%PDF-");
|
|
758
748
|
}
|
|
759
749
|
function readDeclaredPageBox(page, key) {
|
|
760
750
|
const arr = require_objects.asArray(require_objects.dictGet(page, key));
|
|
@@ -813,4 +803,7 @@ function readPageContentBytes(page, resolver, sink) {
|
|
|
813
803
|
return /* @__PURE__ */ new Uint8Array(0);
|
|
814
804
|
}
|
|
815
805
|
//#endregion
|
|
806
|
+
exports.drawGlyphOutline = drawGlyphOutline;
|
|
807
|
+
exports.flattenCubic = flattenCubic;
|
|
808
|
+
exports.glyphOutlineSubpaths = glyphOutlineSubpaths;
|
|
816
809
|
exports.renderPdfPage = renderPdfPage;
|
package/dist/raster.d.cts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
+
import { r as Matrix } from "./matrix-B7_SBKQ5.cjs";
|
|
3
|
+
import { n as GlyphOutline } from "./glyf-contours-zRQbj-Yp.cjs";
|
|
2
4
|
import { Color } from "document-schema.js";
|
|
3
5
|
//#region src/raster.d.ts
|
|
4
6
|
type RasterMatrix = readonly [number, number, number, number, number, number];
|
|
@@ -79,5 +81,23 @@ interface RenderPdfPageOptions {
|
|
|
79
81
|
readonly signal?: AbortSignal;
|
|
80
82
|
}
|
|
81
83
|
declare function renderPdfPage(pdfBytes: Uint8Array<ArrayBuffer>, pageIndex: number, options: RenderPdfPageOptions, rasteriser: PageRasteriser): Uint8Array<ArrayBuffer> | Promise<Uint8Array<ArrayBuffer>>;
|
|
84
|
+
declare function flattenCubic(p0: {
|
|
85
|
+
x: number;
|
|
86
|
+
y: number;
|
|
87
|
+
}, c1: {
|
|
88
|
+
x: number;
|
|
89
|
+
y: number;
|
|
90
|
+
}, c2: {
|
|
91
|
+
x: number;
|
|
92
|
+
y: number;
|
|
93
|
+
}, p1: {
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
}): readonly {
|
|
97
|
+
x: number;
|
|
98
|
+
y: number;
|
|
99
|
+
}[];
|
|
100
|
+
declare function drawGlyphOutline(outline: GlyphOutline, glyphMatrix: Matrix, color: Color, rasteriser: PageRasteriser): void;
|
|
101
|
+
declare function glyphOutlineSubpaths(outline: GlyphOutline, matrix: Matrix): readonly RasterSubpath[];
|
|
82
102
|
//#endregion
|
|
83
|
-
export { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, renderPdfPage };
|
|
103
|
+
export { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, drawGlyphOutline, flattenCubic, glyphOutlineSubpaths, renderPdfPage };
|
package/dist/raster.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
+
import { r as Matrix } from "./matrix-B7_SBKQ5.js";
|
|
3
|
+
import { n as GlyphOutline } from "./glyf-contours-OSdG6Edr.js";
|
|
2
4
|
import { Color } from "document-schema.js";
|
|
3
5
|
//#region src/raster.d.ts
|
|
4
6
|
type RasterMatrix = readonly [number, number, number, number, number, number];
|
|
@@ -79,5 +81,23 @@ interface RenderPdfPageOptions {
|
|
|
79
81
|
readonly signal?: AbortSignal;
|
|
80
82
|
}
|
|
81
83
|
declare function renderPdfPage(pdfBytes: Uint8Array<ArrayBuffer>, pageIndex: number, options: RenderPdfPageOptions, rasteriser: PageRasteriser): Uint8Array<ArrayBuffer> | Promise<Uint8Array<ArrayBuffer>>;
|
|
84
|
+
declare function flattenCubic(p0: {
|
|
85
|
+
x: number;
|
|
86
|
+
y: number;
|
|
87
|
+
}, c1: {
|
|
88
|
+
x: number;
|
|
89
|
+
y: number;
|
|
90
|
+
}, c2: {
|
|
91
|
+
x: number;
|
|
92
|
+
y: number;
|
|
93
|
+
}, p1: {
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
}): readonly {
|
|
97
|
+
x: number;
|
|
98
|
+
y: number;
|
|
99
|
+
}[];
|
|
100
|
+
declare function drawGlyphOutline(outline: GlyphOutline, glyphMatrix: Matrix, color: Color, rasteriser: PageRasteriser): void;
|
|
101
|
+
declare function glyphOutlineSubpaths(outline: GlyphOutline, matrix: Matrix): readonly RasterSubpath[];
|
|
82
102
|
//#endregion
|
|
83
|
-
export { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, renderPdfPage };
|
|
103
|
+
export { PageRasteriser, RasterDrawOp, RasterFillRectOp, RasterFillSpec, RasterImageOp, RasterMatrix, RasterPageGeometry, RasterPathOp, RasterPathSegment, RasterRegionPt, RasterStrokeSpec, RasterSubpath, RenderPdfPageOptions, drawGlyphOutline, flattenCubic, glyphOutlineSubpaths, renderPdfPage };
|
package/dist/raster.js
CHANGED
|
@@ -16,7 +16,6 @@ import { normalizeRotation, pageRotationTransform } from "./read.js";
|
|
|
16
16
|
import { parseGlyf } from "./glyf.js";
|
|
17
17
|
import { decodeGlyphOutline } from "./glyf-contours.js";
|
|
18
18
|
//#region src/raster.ts
|
|
19
|
-
const FALLBACK_GLYPH_WIDTH_PER_1000 = 500;
|
|
20
19
|
function regionPixels(extentPt, scale) {
|
|
21
20
|
return Math.max(1, Math.ceil(extentPt * scale - 1e-9));
|
|
22
21
|
}
|
|
@@ -45,7 +44,7 @@ function renderPdfPage(pdfBytes, pageIndex, options, rasteriser) {
|
|
|
45
44
|
cropBox = mediaBox;
|
|
46
45
|
}
|
|
47
46
|
const rotation = normalizeRotation(asNumber(dictGet(page, "Rotate")));
|
|
48
|
-
const rotationResult = pageRotationTransform(rotation,
|
|
47
|
+
const rotationResult = pageRotationTransform(rotation, 0, 0);
|
|
49
48
|
const visibleRect = rotatedRectBounds(cropBox, rotationResult.matrix);
|
|
50
49
|
const pageWidthPt = visibleRect.maxX - visibleRect.minX;
|
|
51
50
|
const pageHeightPt = visibleRect.maxY - visibleRect.minY;
|
|
@@ -482,7 +481,7 @@ function openEmbeddedProgram(descriptorOwner, resolver) {
|
|
|
482
481
|
const stream = resolver.resolve(dictGet(descriptor, key));
|
|
483
482
|
if (stream?.kind !== "stream") continue;
|
|
484
483
|
const bytes = decodeStream(stream.raw, stream.dict, NOOP_DIAGNOSTIC_SINK).bytes;
|
|
485
|
-
if (bytes
|
|
484
|
+
if (bytes[0] === 1 && bytes[1] === 0 && bytes[2] === 4) return { kind: "cff" };
|
|
486
485
|
const sfnt = parseSfnt(bytes);
|
|
487
486
|
if (sfnt === void 0) continue;
|
|
488
487
|
if (sfnt.tables.has("CFF ")) return { kind: "cff" };
|
|
@@ -498,10 +497,8 @@ function openEmbeddedProgram(descriptorOwner, resolver) {
|
|
|
498
497
|
kind: "glyf",
|
|
499
498
|
sfnt,
|
|
500
499
|
face: {
|
|
501
|
-
composite: false,
|
|
502
500
|
glyf,
|
|
503
|
-
unitsPerEm: head.unitsPerEm
|
|
504
|
-
glyphIdOf: () => void 0
|
|
501
|
+
unitsPerEm: head.unitsPerEm
|
|
505
502
|
}
|
|
506
503
|
};
|
|
507
504
|
}
|
|
@@ -573,17 +570,15 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
|
|
|
573
570
|
const entries = [];
|
|
574
571
|
for (let i = 0; i + 1 < decodedBytes.length; i += 2) entries.push(decodedBytes[i] << 8 | decodedBytes[i + 1]);
|
|
575
572
|
return {
|
|
576
|
-
composite: true,
|
|
577
573
|
glyf: program.face.glyf,
|
|
578
574
|
unitsPerEm: program.face.unitsPerEm,
|
|
579
575
|
glyphIdOf: (codes, offset) => {
|
|
580
576
|
const cid = codes[offset] << 8 | codes[offset + 1];
|
|
581
|
-
return
|
|
577
|
+
return entries[cid];
|
|
582
578
|
}
|
|
583
579
|
};
|
|
584
580
|
}
|
|
585
581
|
return {
|
|
586
|
-
composite: true,
|
|
587
582
|
glyf: program.face.glyf,
|
|
588
583
|
unitsPerEm: program.face.unitsPerEm,
|
|
589
584
|
glyphIdOf: (codes, offset) => codes[offset] << 8 | codes[offset + 1]
|
|
@@ -605,7 +600,6 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
|
|
|
605
600
|
return;
|
|
606
601
|
}
|
|
607
602
|
return {
|
|
608
|
-
composite: false,
|
|
609
603
|
glyf: program.face.glyf,
|
|
610
604
|
unitsPerEm: program.face.unitsPerEm,
|
|
611
605
|
glyphIdOf: (codes, offset) => {
|
|
@@ -623,14 +617,13 @@ function buildTextOutlineFace(fontDict, resolver, fontResolver, fontResourceName
|
|
|
623
617
|
function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDeviceMatrix, rasteriser, sink) {
|
|
624
618
|
const face = resolveTextOutlineFace(item.fontResourceName, item.resources, resolver, fontResolver, outlineFaces, sink);
|
|
625
619
|
if (face === void 0) return;
|
|
626
|
-
const composite = face.composite;
|
|
627
620
|
const placements = [];
|
|
628
621
|
let offset = 0;
|
|
629
622
|
let cumulative = 0;
|
|
630
623
|
while (offset < item.codes.length) {
|
|
631
624
|
const advance = fontResolver.metrics.glyphAdvance(item.fontResourceName, item.resources, item.codes, offset);
|
|
632
|
-
const widthPer1000 = advance
|
|
633
|
-
const byteLength = advance
|
|
625
|
+
const widthPer1000 = advance.widthPer1000;
|
|
626
|
+
const byteLength = advance.byteLengthConsumed;
|
|
634
627
|
placements.push({
|
|
635
628
|
glyphId: face.glyphIdOf(item.codes, offset),
|
|
636
629
|
advance: cumulative
|
|
@@ -659,20 +652,23 @@ function drawTextRun(item, fontResolver, resolver, outlineFaces, interpretToDevi
|
|
|
659
652
|
for (const placement of placements) {
|
|
660
653
|
if (placement.glyphId === void 0) continue;
|
|
661
654
|
const outline = decodeGlyphOutline(face.glyf, placement.glyphId);
|
|
662
|
-
if (outline === void 0
|
|
655
|
+
if (outline === void 0) continue;
|
|
663
656
|
const trm = multiplyMatrices(translationMatrix(placement.advance * correction, 0), item.startMatrix);
|
|
664
|
-
|
|
665
|
-
if (subpaths.length === 0) continue;
|
|
666
|
-
rasteriser.draw({
|
|
667
|
-
kind: "path",
|
|
668
|
-
subpaths,
|
|
669
|
-
fill: {
|
|
670
|
-
color: item.color,
|
|
671
|
-
fillRule: "nonzero"
|
|
672
|
-
}
|
|
673
|
-
});
|
|
657
|
+
drawGlyphOutline(outline, multiplyMatrices(glyphScale, multiplyMatrices(trm, interpretToDeviceMatrix)), item.color, rasteriser);
|
|
674
658
|
}
|
|
675
659
|
}
|
|
660
|
+
function drawGlyphOutline(outline, glyphMatrix, color, rasteriser) {
|
|
661
|
+
const subpaths = glyphOutlineSubpaths(outline, glyphMatrix);
|
|
662
|
+
if (subpaths.length === 0) return;
|
|
663
|
+
rasteriser.draw({
|
|
664
|
+
kind: "path",
|
|
665
|
+
subpaths,
|
|
666
|
+
fill: {
|
|
667
|
+
color,
|
|
668
|
+
fillRule: "nonzero"
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
}
|
|
676
672
|
function glyphOutlineSubpaths(outline, matrix) {
|
|
677
673
|
const subpaths = [];
|
|
678
674
|
for (const contour of outline.contours) {
|
|
@@ -683,8 +679,9 @@ function glyphOutlineSubpaths(outline, matrix) {
|
|
|
683
679
|
y: point.y,
|
|
684
680
|
onCurve: point.onCurve
|
|
685
681
|
}));
|
|
686
|
-
const
|
|
687
|
-
|
|
682
|
+
const hasLeadingOnCurvePoint = firstOn >= 0;
|
|
683
|
+
const ordered = hasLeadingOnCurvePoint ? [...contourPoints.slice(firstOn), ...contourPoints.slice(0, firstOn)] : contourPoints;
|
|
684
|
+
let current = hasLeadingOnCurvePoint ? {
|
|
688
685
|
x: contourPoints[firstOn].x,
|
|
689
686
|
y: contourPoints[firstOn].y
|
|
690
687
|
} : {
|
|
@@ -733,27 +730,20 @@ function glyphOutlineSubpaths(outline, matrix) {
|
|
|
733
730
|
pendingOffCurve = point;
|
|
734
731
|
}
|
|
735
732
|
if (pendingOffCurve !== void 0) emitQuad(current, pendingOffCurve, start);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
});
|
|
744
|
-
}
|
|
733
|
+
const startPx = applyMatrix(matrix, start);
|
|
734
|
+
subpaths.push({
|
|
735
|
+
startXPx: startPx.x,
|
|
736
|
+
startYPx: startPx.y,
|
|
737
|
+
segments,
|
|
738
|
+
closed: true
|
|
739
|
+
});
|
|
745
740
|
}
|
|
746
741
|
return subpaths;
|
|
747
742
|
}
|
|
748
|
-
const PDF_HEADER_BYTES = new TextEncoder().encode("%PDF-");
|
|
749
743
|
const HEADER_SEARCH_WINDOW = 1024;
|
|
750
744
|
function hasPdfHeader(bytes) {
|
|
751
745
|
const window = bytes.subarray(0, Math.min(HEADER_SEARCH_WINDOW, bytes.length));
|
|
752
|
-
|
|
753
|
-
for (let j = 0; j < PDF_HEADER_BYTES.length; j++) if (window[i + j] !== PDF_HEADER_BYTES[j]) continue outer;
|
|
754
|
-
return true;
|
|
755
|
-
}
|
|
756
|
-
return false;
|
|
746
|
+
return new TextDecoder("latin1").decode(window).includes("%PDF-");
|
|
757
747
|
}
|
|
758
748
|
function readDeclaredPageBox(page, key) {
|
|
759
749
|
const arr = asArray(dictGet(page, key));
|
|
@@ -812,4 +802,4 @@ function readPageContentBytes(page, resolver, sink) {
|
|
|
812
802
|
return /* @__PURE__ */ new Uint8Array(0);
|
|
813
803
|
}
|
|
814
804
|
//#endregion
|
|
815
|
-
export { renderPdfPage };
|
|
805
|
+
export { drawGlyphOutline, flattenCubic, glyphOutlineSubpaths, renderPdfPage };
|
package/dist/read.cjs
CHANGED
|
@@ -288,7 +288,7 @@ function readPage(pageIndex, page, resolver, fontResolver, images, imageIdCache,
|
|
|
288
288
|
});
|
|
289
289
|
cropBox = mediaBox;
|
|
290
290
|
}
|
|
291
|
-
const rotationResult = pageRotationTransform(normalizeRotation(require_objects.asNumber(require_objects.dictGet(page, "Rotate"))),
|
|
291
|
+
const rotationResult = pageRotationTransform(normalizeRotation(require_objects.asNumber(require_objects.dictGet(page, "Rotate"))), 0, 0);
|
|
292
292
|
const visibleRect = rotatedRectBounds(cropBox, rotationResult.matrix);
|
|
293
293
|
const widthPt = visibleRect.maxX - visibleRect.minX;
|
|
294
294
|
const heightPt = visibleRect.maxY - visibleRect.minY;
|
package/dist/read.js
CHANGED
|
@@ -287,7 +287,7 @@ function readPage(pageIndex, page, resolver, fontResolver, images, imageIdCache,
|
|
|
287
287
|
});
|
|
288
288
|
cropBox = mediaBox;
|
|
289
289
|
}
|
|
290
|
-
const rotationResult = pageRotationTransform(normalizeRotation(asNumber(dictGet(page, "Rotate"))),
|
|
290
|
+
const rotationResult = pageRotationTransform(normalizeRotation(asNumber(dictGet(page, "Rotate"))), 0, 0);
|
|
291
291
|
const visibleRect = rotatedRectBounds(cropBox, rotationResult.matrix);
|
|
292
292
|
const widthPt = visibleRect.maxX - visibleRect.minX;
|
|
293
293
|
const heightPt = visibleRect.maxY - visibleRect.minY;
|
package/dist/serialize.cjs
CHANGED
|
@@ -6,13 +6,9 @@ const NUMBER_DECIMAL_PLACES = 4;
|
|
|
6
6
|
const NUMBER_EPSILON = 10 ** -4;
|
|
7
7
|
function formatNumber(n) {
|
|
8
8
|
if (Math.abs(n) < NUMBER_EPSILON) return "0";
|
|
9
|
-
|
|
10
|
-
if (formatted.includes(".")) formatted = formatted.replace(/0+$/, "").replace(/\.$/, "");
|
|
11
|
-
return formatted === "-0" ? "0" : formatted;
|
|
9
|
+
return n.toFixed(NUMBER_DECIMAL_PLACES).replace(/0+$/, "").replace(/\.$/, "");
|
|
12
10
|
}
|
|
13
|
-
const NAME_ESCAPE_PATTERN = /[^!-~]|[#()<>[\]{}/%]/;
|
|
14
11
|
function escapeName(name) {
|
|
15
|
-
if (!NAME_ESCAPE_PATTERN.test(name)) return name;
|
|
16
12
|
let out = "";
|
|
17
13
|
for (const ch of name) {
|
|
18
14
|
const code = ch.codePointAt(0);
|
package/dist/serialize.js
CHANGED
|
@@ -5,13 +5,9 @@ const NUMBER_DECIMAL_PLACES = 4;
|
|
|
5
5
|
const NUMBER_EPSILON = 10 ** -4;
|
|
6
6
|
function formatNumber(n) {
|
|
7
7
|
if (Math.abs(n) < NUMBER_EPSILON) return "0";
|
|
8
|
-
|
|
9
|
-
if (formatted.includes(".")) formatted = formatted.replace(/0+$/, "").replace(/\.$/, "");
|
|
10
|
-
return formatted === "-0" ? "0" : formatted;
|
|
8
|
+
return n.toFixed(NUMBER_DECIMAL_PLACES).replace(/0+$/, "").replace(/\.$/, "");
|
|
11
9
|
}
|
|
12
|
-
const NAME_ESCAPE_PATTERN = /[^!-~]|[#()<>[\]{}/%]/;
|
|
13
10
|
function escapeName(name) {
|
|
14
|
-
if (!NAME_ESCAPE_PATTERN.test(name)) return name;
|
|
15
11
|
let out = "";
|
|
16
12
|
for (const ch of name) {
|
|
17
13
|
const code = ch.codePointAt(0);
|
package/dist/write.cjs
CHANGED
|
@@ -74,14 +74,10 @@ function computeFontFlags(standardName, metrics) {
|
|
|
74
74
|
if (standardName.includes("Bold")) flags |= FLAG_FORCE_BOLD;
|
|
75
75
|
return flags;
|
|
76
76
|
}
|
|
77
|
-
function widthForWidthsArray(standardName, code) {
|
|
78
|
-
if (require_afm_widths.STANDARD_METRICS[standardName].fixedWidth === void 0 && require_afm_widths.winAnsiGlyphName(code) === void 0) return 0;
|
|
79
|
-
return require_afm_widths.widthOfCode(standardName, code);
|
|
80
|
-
}
|
|
81
77
|
function buildFontObjects(standardName, descriptorRef) {
|
|
82
78
|
const metrics = require_afm_widths.STANDARD_METRICS[standardName];
|
|
83
79
|
const widths = [];
|
|
84
|
-
for (let code = FIRST_CHAR; code <= LAST_CHAR; code++) widths.push(require_objects.pdfNum(
|
|
80
|
+
for (let code = FIRST_CHAR; code <= LAST_CHAR; code++) widths.push(require_objects.pdfNum(require_afm_widths.widthOfCode(standardName, code)));
|
|
85
81
|
return {
|
|
86
82
|
font: require_objects.pdfDict({
|
|
87
83
|
Type: require_objects.pdfName("Font"),
|
package/dist/write.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as widthOfCode,
|
|
1
|
+
import { n as widthOfCode, t as STANDARD_METRICS } from "./afm-widths-De_QMWgC.js";
|
|
2
2
|
import { NOTES_ANNOTATION_AUTHOR } from "./notes-annotation-author.js";
|
|
3
3
|
import { pdfArray, pdfBool, pdfDict, pdfHexString, pdfLiteralString, pdfName, pdfNull, pdfNum, pdfRef, pdfStream } from "./objects.js";
|
|
4
4
|
import { ByteWriter, concatBytes } from "./bytes/writer.js";
|
|
@@ -73,14 +73,10 @@ function computeFontFlags(standardName, metrics) {
|
|
|
73
73
|
if (standardName.includes("Bold")) flags |= FLAG_FORCE_BOLD;
|
|
74
74
|
return flags;
|
|
75
75
|
}
|
|
76
|
-
function widthForWidthsArray(standardName, code) {
|
|
77
|
-
if (STANDARD_METRICS[standardName].fixedWidth === void 0 && winAnsiGlyphName(code) === void 0) return 0;
|
|
78
|
-
return widthOfCode(standardName, code);
|
|
79
|
-
}
|
|
80
76
|
function buildFontObjects(standardName, descriptorRef) {
|
|
81
77
|
const metrics = STANDARD_METRICS[standardName];
|
|
82
78
|
const widths = [];
|
|
83
|
-
for (let code = FIRST_CHAR; code <= LAST_CHAR; code++) widths.push(pdfNum(
|
|
79
|
+
for (let code = FIRST_CHAR; code <= LAST_CHAR; code++) widths.push(pdfNum(widthOfCode(standardName, code)));
|
|
84
80
|
return {
|
|
85
81
|
font: pdfDict({
|
|
86
82
|
Type: pdfName("Font"),
|
package/dist/xmp.cjs
CHANGED
|
@@ -15,7 +15,7 @@ function readXmpMetadata(packet) {
|
|
|
15
15
|
function xmpValue(packet, element) {
|
|
16
16
|
const match = new RegExp(`<${element}(?:\\s[^>]*)?>([\\s\\S]*?)</${element}>`).exec(packet);
|
|
17
17
|
if (match === null) return;
|
|
18
|
-
const inner = match[1]
|
|
18
|
+
const inner = match[1];
|
|
19
19
|
const items = listItems(inner);
|
|
20
20
|
if (items.length > 0) return items;
|
|
21
21
|
const text = inner.trim();
|
|
@@ -26,7 +26,7 @@ function listItems(inner) {
|
|
|
26
26
|
const pattern = /<rdf:li(?:\s[^>]*)?>([\s\S]*?)<\/rdf:li>/g;
|
|
27
27
|
let match;
|
|
28
28
|
while ((match = pattern.exec(inner)) !== null) {
|
|
29
|
-
const text =
|
|
29
|
+
const text = match[1].trim();
|
|
30
30
|
if (text.length > 0) items.push(text);
|
|
31
31
|
}
|
|
32
32
|
return items;
|
|
@@ -39,7 +39,7 @@ function field(value, key) {
|
|
|
39
39
|
function keywordsOf(packet) {
|
|
40
40
|
const match = (/* @__PURE__ */ new RegExp("<dc:subject(?:\\s[^>]*)?>([\\s\\S]*?)</dc:subject>")).exec(packet);
|
|
41
41
|
if (match === null) return {};
|
|
42
|
-
const items = listItems(match[1]
|
|
42
|
+
const items = listItems(match[1]);
|
|
43
43
|
return items.length > 0 ? { keywords: items } : {};
|
|
44
44
|
}
|
|
45
45
|
//#endregion
|
package/dist/xmp.js
CHANGED
|
@@ -14,7 +14,7 @@ function readXmpMetadata(packet) {
|
|
|
14
14
|
function xmpValue(packet, element) {
|
|
15
15
|
const match = new RegExp(`<${element}(?:\\s[^>]*)?>([\\s\\S]*?)</${element}>`).exec(packet);
|
|
16
16
|
if (match === null) return;
|
|
17
|
-
const inner = match[1]
|
|
17
|
+
const inner = match[1];
|
|
18
18
|
const items = listItems(inner);
|
|
19
19
|
if (items.length > 0) return items;
|
|
20
20
|
const text = inner.trim();
|
|
@@ -25,7 +25,7 @@ function listItems(inner) {
|
|
|
25
25
|
const pattern = /<rdf:li(?:\s[^>]*)?>([\s\S]*?)<\/rdf:li>/g;
|
|
26
26
|
let match;
|
|
27
27
|
while ((match = pattern.exec(inner)) !== null) {
|
|
28
|
-
const text =
|
|
28
|
+
const text = match[1].trim();
|
|
29
29
|
if (text.length > 0) items.push(text);
|
|
30
30
|
}
|
|
31
31
|
return items;
|
|
@@ -38,7 +38,7 @@ function field(value, key) {
|
|
|
38
38
|
function keywordsOf(packet) {
|
|
39
39
|
const match = (/* @__PURE__ */ new RegExp("<dc:subject(?:\\s[^>]*)?>([\\s\\S]*?)</dc:subject>")).exec(packet);
|
|
40
40
|
if (match === null) return {};
|
|
41
|
-
const items = listItems(match[1]
|
|
41
|
+
const items = listItems(match[1]);
|
|
42
42
|
return items.length > 0 ? { keywords: items } : {};
|
|
43
43
|
}
|
|
44
44
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf-parser.js",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.12",
|
|
4
4
|
"description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on its own codec-owned LayoutDocument item model and Zod 4 codecs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|