diff --git a/src/core/annotation.js b/src/core/annotation.js index c4d4f609a..8e4c94ec4 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -1232,8 +1232,7 @@ class Annotation { separateCanvas: false, }; } - appearance = new StringStream(""); - appearance.dict = new Dict(); + appearance = new StringStream("", new Dict()); } const appearanceDict = appearance.dict; @@ -1782,8 +1781,10 @@ class MarkupAnnotation extends Annotation { const appearanceStreamDict = new Dict(xref); appearanceStreamDict.setIfName("Subtype", "Form"); - const appearanceStream = new StringStream(buffer.join(" ")); - appearanceStream.dict = appearanceStreamDict; + const appearanceStream = new StringStream( + buffer.join(" "), + appearanceStreamDict + ); formDict.set("Fm0", appearanceStream); const gsDict = new Dict(xref); @@ -1804,8 +1805,7 @@ class MarkupAnnotation extends Annotation { appearanceDict.set("Resources", resources); appearanceDict.set("BBox", bbox); - this.appearance = new StringStream("/GS0 gs /Fm0 Do"); - this.appearance.dict = appearanceDict; + this.appearance = new StringStream("/GS0 gs /Fm0 Do", appearanceDict); // This method is only called if there is no appearance for the annotation, // so `this.appearance` is not pushed yet in the `Annotation` constructor. @@ -2292,9 +2292,8 @@ class WidgetAnnotation extends Annotation { dict.set("AP", AP); AP.set("N", newRef); - const resources = this._getSaveFieldResources(xref); - const appearanceStream = new StringStream(appearance); - const appearanceDict = (appearanceStream.dict = new Dict(xref)); + const resources = this._getSaveFieldResources(xref), + appearanceDict = new Dict(xref); appearanceDict.setIfName("Subtype", "Form"); appearanceDict.set("Resources", resources); const bbox = @@ -2303,6 +2302,8 @@ class WidgetAnnotation extends Annotation { : [0, 0, this.height, this.width]; appearanceDict.set("BBox", bbox); + const appearanceStream = new StringStream(appearance, appearanceDict); + const rotationMatrix = this.getRotationMatrix(annotationStorage); if (rotationMatrix !== IDENTITY_MATRIX) { // The matrix isn't the identity one. @@ -3402,8 +3403,7 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { appearanceStreamDict.set("Resources", resources); - this.checkedAppearance = new StringStream(appearance); - this.checkedAppearance.dict = appearanceStreamDict; + this.checkedAppearance = new StringStream(appearance, appearanceStreamDict); this._streams.push(this.checkedAppearance); } @@ -4253,10 +4253,7 @@ class FreeTextAnnotation extends MarkupAnnotation { appearanceStreamDict.set("Resources", resources); appearanceStreamDict.set("Matrix", [1, 0, 0, 1, -rect[0], -rect[1]]); - const ap = new StringStream(appearance); - ap.dict = appearanceStreamDict; - - return ap; + return new StringStream(appearance, appearanceStreamDict); } } @@ -4745,10 +4742,7 @@ class InkAnnotation extends MarkupAnnotation { appearanceStreamDict.set("Resources", resources); } - const ap = new StringStream(appearance); - ap.dict = appearanceStreamDict; - - return ap; + return new StringStream(appearance, appearanceStreamDict); } static async createNewAppearanceStreamForHighlight(annotation, xref, params) { @@ -4806,10 +4800,7 @@ class InkAnnotation extends MarkupAnnotation { r0.setIfName("Type", "ExtGState"); } - const ap = new StringStream(appearance); - ap.dict = appearanceStreamDict; - - return ap; + return new StringStream(appearance, appearanceStreamDict); } } @@ -4949,10 +4940,7 @@ class HighlightAnnotation extends MarkupAnnotation { r0.setIfName("Type", "ExtGState"); } - const ap = new StringStream(appearance); - ap.dict = appearanceStreamDict; - - return ap; + return new StringStream(appearance, appearanceStreamDict); } } @@ -5179,10 +5167,7 @@ class StampAnnotation extends MarkupAnnotation { appearanceStreamDict.set("BBox", rect); appearanceStreamDict.set("Length", appearance.length); - const ap = new StringStream(appearance); - ap.dict = appearanceStreamDict; - - return ap; + return new StringStream(appearance, appearanceStreamDict); } static async createNewAppearanceStream(annotation, xref, params) { @@ -5214,10 +5199,7 @@ class StampAnnotation extends MarkupAnnotation { appearanceStreamDict.set("Matrix", matrix); } - const ap = new StringStream(appearance); - ap.dict = appearanceStreamDict; - - return ap; + return new StringStream(appearance, appearanceStreamDict); } } diff --git a/src/core/default_appearance.js b/src/core/default_appearance.js index 01114baeb..43573cef6 100644 --- a/src/core/default_appearance.js +++ b/src/core/default_appearance.js @@ -479,10 +479,7 @@ class FakeUnicodeFont { appearanceStreamDict.set("Matrix", matrix); } - const ap = new StringStream(appearance); - ap.dict = appearanceStreamDict; - - return ap; + return new StringStream(appearance, appearanceStreamDict); } } diff --git a/src/core/editor/pdf_editor.js b/src/core/editor/pdf_editor.js index d55354092..f1945f41b 100644 --- a/src/core/editor/pdf_editor.js +++ b/src/core/editor/pdf_editor.js @@ -30,12 +30,12 @@ import { import { Dict, isName, Name, Ref, RefSet, RefSetCache } from "../primitives.js"; import { incrementalUpdate, writeValue } from "../writer.js"; import { NameTree, NumberTree } from "../name_number_tree.js"; -import { Stream, StringStream } from "../stream.js"; import { stringToAsciiOrUTF16BE, stringToPDFString } from "../string_utils.js"; import { AnnotationFactory } from "../annotation.js"; import { BaseStream } from "../base_stream.js"; import { createImage } from "./pdf_images.js"; import { LETTER_SIZE_MEDIABOX } from "../document.js"; +import { StringStream } from "../stream.js"; import { stringToBytes } from "../../shared/util.js"; const MAX_LEAVES_PER_PAGES_NODE = 16; @@ -2374,12 +2374,9 @@ class PDFEditor { const content = `q ${numberToString(drawW)} 0 0 ${numberToString(drawH)} ` + `${numberToString(tx)} ${numberToString(ty)} cm /Im0 Do Q`; - const contentsDict = new Dict(this.xrefWrapper); - const contentsStream = new Stream( - stringToBytes(content), - 0, - 0, - contentsDict + const contentsStream = new StringStream( + content, + new Dict(this.xrefWrapper) ); const contentsRef = this.newRef; this.xref[contentsRef.num] = contentsStream; @@ -2805,11 +2802,11 @@ class PDFEditor { offset += obj.length + 1; } streamBuffer[0] = objOffsets.join("\n"); - const objStream = new StringStream(streamBuffer.join("\n")); - const objStreamDict = (objStream.dict = new Dict()); - objStreamDict.setIfName("Type", "ObjStm"); - objStreamDict.set("N", objRefs.length); - objStreamDict.set("First", streamBuffer[0].length + 1); + const dict = new Dict(); + dict.setIfName("Type", "ObjStm"); + dict.set("N", objRefs.length); + dict.set("First", streamBuffer[0].length + 1); + const objStream = new StringStream(streamBuffer.join("\n"), dict); changes.put(objStreamRef, { data: objStream }); } diff --git a/src/core/stream.js b/src/core/stream.js index e47be2ccd..41581f37f 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -95,8 +95,8 @@ class Stream extends BaseStream { } class StringStream extends Stream { - constructor(str) { - super(stringToBytes(str)); + constructor(str, dict = null) { + super(stringToBytes(str), NaN, NaN, dict); } } diff --git a/src/core/writer.js b/src/core/writer.js index e4cb4c8ac..63f5d195e 100644 --- a/src/core/writer.js +++ b/src/core/writer.js @@ -288,8 +288,7 @@ function updateXFA({ xfaData, xfaDatasetsRef, changes, xref }) { const datasets = xref.fetchIfRef(xfaDatasetsRef); xfaData = writeXFADataForAcroform(datasets.getString(), changes); } - const xfaDataStream = new StringStream(xfaData); - xfaDataStream.dict = new Dict(xref); + const xfaDataStream = new StringStream(xfaData, new Dict(xref)); xfaDataStream.dict.setIfName("Type", "EmbeddedFile"); changes.put(xfaDatasetsRef, { diff --git a/test/unit/annotation_spec.js b/test/unit/annotation_spec.js index cf364a521..f4520e1ea 100644 --- a/test/unit/annotation_spec.js +++ b/test/unit/annotation_spec.js @@ -1737,8 +1737,10 @@ describe("annotation", function () { const appearanceStatesDict = new Dict(); const normalAppearanceDict = new Dict(); - const normalAppearanceStream = new StringStream("0.1 0.2 0.3 rg"); - normalAppearanceStream.dict = normalAppearanceDict; + const normalAppearanceStream = new StringStream( + "0.1 0.2 0.3 rg", + normalAppearanceDict + ); appearanceStatesDict.set("N", normalAppearanceStream); textWidgetDict.set("AP", appearanceStatesDict); @@ -2549,11 +2551,12 @@ describe("annotation", function () { const checkedAppearanceDict = new Dict(); const uncheckedAppearanceDict = new Dict(); - const checkedStream = new StringStream("/ 12 Tf (4) Tj"); - checkedStream.dict = checkedAppearanceDict; + const checkedStream = new StringStream( + "/ 12 Tf (4) Tj", + checkedAppearanceDict + ); - const uncheckedStream = new StringStream(""); - uncheckedStream.dict = uncheckedAppearanceDict; + const uncheckedStream = new StringStream("", uncheckedAppearanceDict); checkedAppearanceDict.set("BBox", [0, 0, 8, 8]); checkedAppearanceDict.set("FormType", 1); @@ -2609,11 +2612,15 @@ describe("annotation", function () { const checkedAppearanceDict = new Dict(); const uncheckedAppearanceDict = new Dict(); - const checkedStream = new StringStream("0.1 0.2 0.3 rg"); - checkedStream.dict = checkedAppearanceDict; + const checkedStream = new StringStream( + "0.1 0.2 0.3 rg", + checkedAppearanceDict + ); - const uncheckedStream = new StringStream("0.3 0.2 0.1 rg"); - uncheckedStream.dict = uncheckedAppearanceDict; + const uncheckedStream = new StringStream( + "0.3 0.2 0.1 rg", + uncheckedAppearanceDict + ); checkedAppearanceDict.set("BBox", [0, 0, 8, 8]); checkedAppearanceDict.set("FormType", 1); @@ -2690,11 +2697,15 @@ describe("annotation", function () { const checkedAppearanceDict = new Dict(); const uncheckedAppearanceDict = new Dict(); - const checkedStream = new StringStream("0.1 0.2 0.3 rg"); - checkedStream.dict = checkedAppearanceDict; + const checkedStream = new StringStream( + "0.1 0.2 0.3 rg", + checkedAppearanceDict + ); - const uncheckedStream = new StringStream("0.3 0.2 0.1 rg"); - uncheckedStream.dict = uncheckedAppearanceDict; + const uncheckedStream = new StringStream( + "0.3 0.2 0.1 rg", + uncheckedAppearanceDict + ); checkedAppearanceDict.set("BBox", [0, 0, 8, 8]); checkedAppearanceDict.set("FormType", 1); @@ -2752,11 +2763,15 @@ describe("annotation", function () { const checkedAppearanceDict = new Dict(); const uncheckedAppearanceDict = new Dict(); - const checkedStream = new StringStream("0.1 0.2 0.3 rg"); - checkedStream.dict = checkedAppearanceDict; + const checkedStream = new StringStream( + "0.1 0.2 0.3 rg", + checkedAppearanceDict + ); - const uncheckedStream = new StringStream("0.3 0.2 0.1 rg"); - uncheckedStream.dict = uncheckedAppearanceDict; + const uncheckedStream = new StringStream( + "0.3 0.2 0.1 rg", + uncheckedAppearanceDict + ); checkedAppearanceDict.set("BBox", [0, 0, 8, 8]); checkedAppearanceDict.set("FormType", 1); @@ -2995,11 +3010,15 @@ describe("annotation", function () { const checkedAppearanceDict = new Dict(); const uncheckedAppearanceDict = new Dict(); - const checkedStream = new StringStream("0.1 0.2 0.3 rg"); - checkedStream.dict = checkedAppearanceDict; + const checkedStream = new StringStream( + "0.1 0.2 0.3 rg", + checkedAppearanceDict + ); - const uncheckedStream = new StringStream("0.3 0.2 0.1 rg"); - uncheckedStream.dict = uncheckedAppearanceDict; + const uncheckedStream = new StringStream( + "0.3 0.2 0.1 rg", + uncheckedAppearanceDict + ); checkedAppearanceDict.set("BBox", [0, 0, 8, 8]); checkedAppearanceDict.set("FormType", 1); @@ -3077,11 +3096,15 @@ describe("annotation", function () { const checkedAppearanceDict = new Dict(); const uncheckedAppearanceDict = new Dict(); - const checkedStream = new StringStream("0.1 0.2 0.3 rg"); - checkedStream.dict = checkedAppearanceDict; + const checkedStream = new StringStream( + "0.1 0.2 0.3 rg", + checkedAppearanceDict + ); - const uncheckedStream = new StringStream("0.3 0.2 0.1 rg"); - uncheckedStream.dict = uncheckedAppearanceDict; + const uncheckedStream = new StringStream( + "0.3 0.2 0.1 rg", + uncheckedAppearanceDict + ); checkedAppearanceDict.set("BBox", [0, 0, 8, 8]); checkedAppearanceDict.set("FormType", 1); diff --git a/test/unit/colorspace_spec.js b/test/unit/colorspace_spec.js index 4c4129ca0..f3bdd8950 100644 --- a/test/unit/colorspace_spec.js +++ b/test/unit/colorspace_spec.js @@ -841,14 +841,13 @@ describe("colorspace", function () { fnDict.set("Range", [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]); fnDict.set("Length", 58); - let fn = new StringStream( + const fn = new StringStream( "{ dup 0.84 mul " + "exch 0.00 exch " + "dup 0.44 mul " + - "exch 0.21 mul }" + "exch 0.21 mul }", + fnDict ); - fn = new Stream(fn.bytes, 0, 58, fnDict); - const fnRef = Ref.get(10, 0); const cs = [ diff --git a/test/unit/default_appearance_spec.js b/test/unit/default_appearance_spec.js index b36c7148d..f0924956f 100644 --- a/test/unit/default_appearance_spec.js +++ b/test/unit/default_appearance_spec.js @@ -19,8 +19,8 @@ import { parseDefaultAppearance, } from "../../src/core/default_appearance.js"; import { Dict, Name } from "../../src/core/primitives.js"; -import { NullStream, StringStream } from "../../src/core/stream.js"; import { GlobalColorSpaceCache } from "../../src/core/image_utils.js"; +import { StringStream } from "../../src/core/stream.js"; import { XRefMock } from "./test_utils.js"; describe("Default appearance", function () { @@ -132,8 +132,7 @@ describe("Default appearance", function () { indexedDict.set("N", 3); indexedDict.set("Length", 0); - const indexedStream = new NullStream(); - indexedStream.dict = indexedDict; + const indexedStream = new StringStream("", indexedDict); const colorSpaceDict = new Dict(xref); colorSpaceDict.set("Cs1", [Name.get("ICCBased"), indexedStream]); @@ -144,13 +143,15 @@ describe("Default appearance", function () { const appearanceDict = new Dict(xref); appearanceDict.set("Resources", resourcesDict); - const appearance = new StringStream(` + const appearance = new StringStream( + ` q Q q 2.128482 2.128482 247.84 26 re W n /Cs1 cs 0.52799 0.3071 0.99498 sc q 1 0 0 -1 -108.3364 459.8485 cm BT 22.00539 0 0 -22.00539 110.5449 452.72 Tm /TT1 1 Tf [ (H) -0.2 (e) -0.2 (l) -0.2 (l) -0.2 (o) -0.2 ( ) 0.2 (W) 17.7 (o) -0.2 (rl) -0.2 (d) -0.2 ( ) 0.2 (f) 0.2 (ro) -0.2 (m ) 0.2 (Pre) -0.2 - (vi) -0.2 (e) -0.2 (w) ] TJ ET Q Q`); - appearance.dict = appearanceDict; + (vi) -0.2 (e) -0.2 (w) ] TJ ET Q Q`, + appearanceDict + ); const result = { fontSize: 22.00539, diff --git a/test/unit/writer_spec.js b/test/unit/writer_spec.js index 430659fd0..b6d12cdd3 100644 --- a/test/unit/writer_spec.js +++ b/test/unit/writer_spec.js @@ -157,8 +157,7 @@ describe("Writer", function () { const gdict = new Dict(null); gdict.set("H", 123.00001); const string = "a stream"; - const stream = new StringStream(string); - stream.dict = new Dict(null); + const stream = new StringStream(string, new Dict()); stream.dict.set("Length", string.length); gdict.set("I", stream);