Add caching to reduce the number of Ref objects

This is similar to the existing caching used to reduced the number of `Cmd` and `Name` objects.
With the `tracemonkey.pdf` file, this patch changes the number of `Ref` objects as follows (in the default viewer):

|          | Loading the first page | Loading *all* the pages |
|----------|------------------------|-------------------------|
| `master` | 332                    | 3265                    |
| `patch`  | 163                    | 996                     |
This commit is contained in:
Jonas Jenwald 2019-05-25 17:40:14 +02:00
parent d95145953c
commit 2fe9f3ff8f
9 changed files with 103 additions and 88 deletions

View File

@ -627,7 +627,7 @@ class PDFDocument {
const { catalog, linearization, } = this;
assert(linearization && linearization.pageFirst === pageIndex);
const ref = new Ref(linearization.objectNumberFirst, 0);
const ref = Ref.get(linearization.objectNumberFirst, 0);
return this.xref.fetchAsync(ref).then((obj) => {
// Ensure that the object that was found is actually a Page dictionary.
if (isDict(obj, 'Page') ||

View File

@ -1697,7 +1697,7 @@ var XRef = (function XRefClosure() {
fetchCompressed(ref, xrefEntry, suppressEncryption = false) {
var tableOffset = xrefEntry.offset;
var stream = this.fetch(new Ref(tableOffset, 0));
var stream = this.fetch(Ref.get(tableOffset, 0));
if (!isStream(stream)) {
throw new FormatError('bad ObjStm stream');
}

View File

@ -150,7 +150,7 @@ class Parser {
if (Number.isInteger(buf1)) { // indirect reference or integer
const num = buf1;
if (Number.isInteger(this.buf1) && isCmd(this.buf2, 'R')) {
const ref = new Ref(num, this.buf1);
const ref = Ref.get(num, this.buf1);
this.shift();
this.shift();
return ref;

View File

@ -14,6 +14,8 @@
*/
/* uses XRef */
import { assert } from '../shared/util';
var EOF = {};
var Name = (function NameClosure() {
@ -176,6 +178,8 @@ var Dict = (function DictClosure() {
})();
var Ref = (function RefClosure() {
const refCache = Object.create(null);
function Ref(num, gen) {
this.num = num;
this.gen = gen;
@ -185,13 +189,19 @@ var Ref = (function RefClosure() {
toString: function Ref_toString() {
// This function is hot, so we make the string as compact as possible.
// |this.gen| is almost always zero, so we treat that case specially.
if (this.gen !== 0) {
return `${this.num}R${this.gen}`;
if (this.gen === 0) {
return `${this.num}R`;
}
return `${this.num}R`;
return `${this.num}R${this.gen}`;
},
};
Ref.get = function(num, gen) {
const key = (gen === 0 ? `${num}R` : `${num}R${gen}`);
const refValue = refCache[key];
return (refValue ? refValue : (refCache[key] = new Ref(num, gen)));
};
return Ref;
})();
@ -277,6 +287,11 @@ function isRef(v) {
}
function isRefsEqual(v1, v2) {
if (typeof PDFJSDev === 'undefined' ||
PDFJSDev.test('!PRODUCTION || TESTING')) {
assert(v1 instanceof Ref && v2 instanceof Ref,
'isRefsEqual: Both parameters should be `Ref`s.');
}
return v1.num === v2.num && v1.gen === v2.gen;
}

View File

@ -494,7 +494,7 @@ var WorkerMessageHandler = {
});
handler.on('GetPageIndex', function wphSetupGetPageIndex(data) {
var ref = new Ref(data.ref.num, data.ref.gen);
var ref = Ref.get(data.ref.num, data.ref.gen);
var catalog = pdfManager.pdfDocument.catalog;
return catalog.getPageIndex(ref);
});

View File

@ -64,7 +64,7 @@ describe('annotation', function() {
annotationDict.set('Type', Name.get('Annot'));
annotationDict.set('Subtype', Name.get('Link'));
const annotationRef = new Ref(10, 0);
const annotationRef = Ref.get(10, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -105,7 +105,7 @@ describe('annotation', function() {
const annotationDict = new Dict();
annotationDict.set('Type', Name.get('Annot'));
const annotationRef = new Ref(1, 0);
const annotationRef = Ref.get(1, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -123,7 +123,7 @@ describe('annotation', function() {
beforeAll(function(done) {
dict = new Dict();
ref = new Ref(1, 0);
ref = Ref.get(1, 0);
done();
});
@ -322,7 +322,7 @@ describe('annotation', function() {
beforeAll(function(done) {
dict = new Dict();
ref = new Ref(1, 0);
ref = Ref.get(1, 0);
done();
});
@ -357,7 +357,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(820, 0);
const annotationRef = Ref.get(820, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -385,7 +385,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(353, 0);
const annotationRef = Ref.get(353, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -418,7 +418,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(8, 0);
const annotationRef = Ref.get(8, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -448,7 +448,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(798, 0);
const annotationRef = Ref.get(798, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -477,7 +477,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(489, 0);
const annotationRef = Ref.get(489, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -506,7 +506,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(489, 0);
const annotationRef = Ref.get(489, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -538,7 +538,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(495, 0);
const annotationRef = Ref.get(495, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -567,7 +567,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(489, 0);
const annotationRef = Ref.get(489, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -604,7 +604,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(88, 0);
const annotationRef = Ref.get(88, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -642,7 +642,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(46, 0);
const annotationRef = Ref.get(46, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -697,7 +697,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('A', actionDict);
const annotationRef = new Ref(12, 0);
const annotationRef = Ref.get(12, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -718,7 +718,7 @@ describe('annotation', function() {
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('Dest', Name.get('LI0'));
const annotationRef = new Ref(583, 0);
const annotationRef = Ref.get(583, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -738,10 +738,10 @@ describe('annotation', function() {
const annotationDict = new Dict();
annotationDict.set('Type', Name.get('Annot'));
annotationDict.set('Subtype', Name.get('Link'));
annotationDict.set('Dest', [new Ref(17, 0), Name.get('XYZ'),
annotationDict.set('Dest', [Ref.get(17, 0), Name.get('XYZ'),
0, 841.89, null]);
const annotationRef = new Ref(10, 0);
const annotationRef = Ref.get(10, 0);
const xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -771,7 +771,7 @@ describe('annotation', function() {
// section 12.3.3, but there are PDF files where it's a dictionary.
annotationDict.set('Dest', destDict);
let annotationRef = new Ref(798, 0);
let annotationRef = Ref.get(798, 0);
let xref = new XRefMock([
{ ref: annotationRef, data: annotationDict, }
]);
@ -802,7 +802,7 @@ describe('annotation', function() {
});
it('should handle unknown field names', function(done) {
const widgetRef = new Ref(20, 0);
const widgetRef = Ref.get(20, 0);
const xref = new XRefMock([
{ ref: widgetRef, data: widgetDict, }
]);
@ -819,7 +819,7 @@ describe('annotation', function() {
function(done) {
widgetDict.set('T', 'foo');
const widgetRef = new Ref(21, 0);
const widgetRef = Ref.get(21, 0);
const xref = new XRefMock([
{ ref: widgetRef, data: widgetDict, }
]);
@ -844,7 +844,7 @@ describe('annotation', function() {
widgetDict.set('Parent', secondParent);
widgetDict.set('T', 'baz');
const widgetRef = new Ref(22, 0);
const widgetRef = Ref.get(22, 0);
const xref = new XRefMock([
{ ref: widgetRef, data: widgetDict, }
]);
@ -866,7 +866,7 @@ describe('annotation', function() {
widgetDict.set('Parent', parentDict);
widgetDict.set('T', 'bar');
const widgetRef = new Ref(22, 0);
const widgetRef = Ref.get(22, 0);
const xref = new XRefMock([
{ ref: widgetRef, data: widgetDict, }
]);
@ -897,7 +897,7 @@ describe('annotation', function() {
it('should handle unknown text alignment, maximum length and flags',
function(done) {
const textWidgetRef = new Ref(124, 0);
const textWidgetRef = Ref.get(124, 0);
const xref = new XRefMock([
{ ref: textWidgetRef, data: textWidgetDict, }
]);
@ -920,7 +920,7 @@ describe('annotation', function() {
textWidgetDict.set('MaxLen', 'five');
textWidgetDict.set('Ff', 'readonly');
const textWidgetRef = new Ref(43, 0);
const textWidgetRef = Ref.get(43, 0);
const xref = new XRefMock([
{ ref: textWidgetRef, data: textWidgetDict, }
]);
@ -944,7 +944,7 @@ describe('annotation', function() {
textWidgetDict.set('Ff', AnnotationFieldFlag.READONLY +
AnnotationFieldFlag.MULTILINE);
const textWidgetRef = new Ref(84, 0);
const textWidgetRef = Ref.get(84, 0);
const xref = new XRefMock([
{ ref: textWidgetRef, data: textWidgetDict, }
]);
@ -963,7 +963,7 @@ describe('annotation', function() {
it('should reject comb fields without a maximum length', function(done) {
textWidgetDict.set('Ff', AnnotationFieldFlag.COMB);
const textWidgetRef = new Ref(46, 0);
const textWidgetRef = Ref.get(46, 0);
const xref = new XRefMock([
{ ref: textWidgetRef, data: textWidgetDict, }
]);
@ -980,7 +980,7 @@ describe('annotation', function() {
textWidgetDict.set('MaxLen', 20);
textWidgetDict.set('Ff', AnnotationFieldFlag.COMB);
const textWidgetRef = new Ref(46, 0);
const textWidgetRef = Ref.get(46, 0);
const xref = new XRefMock([
{ ref: textWidgetRef, data: textWidgetDict, }
]);
@ -1012,7 +1012,7 @@ describe('annotation', function() {
textWidgetDict.set('MaxLen', 20);
textWidgetDict.set('Ff', flags);
const textWidgetRef = new Ref(93, 0);
const textWidgetRef = Ref.get(93, 0);
const xref = new XRefMock([
{ ref: textWidgetRef, data: textWidgetDict, }
]);
@ -1061,7 +1061,7 @@ describe('annotation', function() {
appearanceStatesDict.set('D', exportValueOptionsDict);
buttonWidgetDict.set('AP', appearanceStatesDict);
const buttonWidgetRef = new Ref(124, 0);
const buttonWidgetRef = Ref.get(124, 0);
const xref = new XRefMock([
{ ref: buttonWidgetRef, data: buttonWidgetDict, }
]);
@ -1080,7 +1080,7 @@ describe('annotation', function() {
it('should handle checkboxes without export value', function(done) {
buttonWidgetDict.set('V', Name.get('1'));
const buttonWidgetRef = new Ref(124, 0);
const buttonWidgetRef = Ref.get(124, 0);
const xref = new XRefMock([
{ ref: buttonWidgetRef, data: buttonWidgetDict, }
]);
@ -1109,7 +1109,7 @@ describe('annotation', function() {
buttonWidgetDict.set('Parent', parentDict);
buttonWidgetDict.set('AP', appearanceStatesDict);
const buttonWidgetRef = new Ref(124, 0);
const buttonWidgetRef = Ref.get(124, 0);
const xref = new XRefMock([
{ ref: buttonWidgetRef, data: buttonWidgetDict, }
]);
@ -1135,7 +1135,7 @@ describe('annotation', function() {
buttonWidgetDict.set('Ff', AnnotationFieldFlag.RADIO);
buttonWidgetDict.set('AP', appearanceStatesDict);
const buttonWidgetRef = new Ref(124, 0);
const buttonWidgetRef = Ref.get(124, 0);
const xref = new XRefMock([
{ ref: buttonWidgetRef, data: buttonWidgetDict, }
]);
@ -1168,7 +1168,7 @@ describe('annotation', function() {
});
it('should handle missing option arrays', function(done) {
const choiceWidgetRef = new Ref(122, 0);
const choiceWidgetRef = Ref.get(122, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, }
]);
@ -1182,9 +1182,9 @@ describe('annotation', function() {
});
it('should handle option arrays with array elements', function(done) {
const optionBarRef = new Ref(20, 0);
const optionBarRef = Ref.get(20, 0);
const optionBarStr = 'Bar';
const optionOneRef = new Ref(10, 0);
const optionOneRef = Ref.get(10, 0);
const optionOneArr = ['bar_export', optionBarRef];
const options = [['foo_export', 'Foo'], optionOneRef];
@ -1195,7 +1195,7 @@ describe('annotation', function() {
choiceWidgetDict.set('Opt', options);
const choiceWidgetRef = new Ref(123, 0);
const choiceWidgetRef = Ref.get(123, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, },
{ ref: optionBarRef, data: optionBarStr, },
@ -1211,7 +1211,7 @@ describe('annotation', function() {
});
it('should handle option arrays with string elements', function(done) {
const optionBarRef = new Ref(10, 0);
const optionBarRef = Ref.get(10, 0);
const optionBarStr = 'Bar';
const options = ['Foo', optionBarRef];
@ -1222,7 +1222,7 @@ describe('annotation', function() {
choiceWidgetDict.set('Opt', options);
const choiceWidgetRef = new Ref(981, 0);
const choiceWidgetRef = Ref.get(981, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, },
{ ref: optionBarRef, data: optionBarStr, }
@ -1251,7 +1251,7 @@ describe('annotation', function() {
choiceWidgetDict.set('Parent', parentDict);
const choiceWidgetRef = new Ref(123, 0);
const choiceWidgetRef = Ref.get(123, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, },
]);
@ -1276,7 +1276,7 @@ describe('annotation', function() {
choiceWidgetDict.set('Opt', options);
const choiceWidgetRef = new Ref(984, 0);
const choiceWidgetRef = Ref.get(984, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, },
]);
@ -1294,7 +1294,7 @@ describe('annotation', function() {
choiceWidgetDict.set('V', fieldValue);
const choiceWidgetRef = new Ref(968, 0);
const choiceWidgetRef = Ref.get(968, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, }
]);
@ -1312,7 +1312,7 @@ describe('annotation', function() {
choiceWidgetDict.set('V', fieldValue);
const choiceWidgetRef = new Ref(978, 0);
const choiceWidgetRef = Ref.get(978, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, }
]);
@ -1326,7 +1326,7 @@ describe('annotation', function() {
});
it('should handle unknown flags', function(done) {
const choiceWidgetRef = new Ref(166, 0);
const choiceWidgetRef = Ref.get(166, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, }
]);
@ -1344,7 +1344,7 @@ describe('annotation', function() {
it('should not set invalid flags', function(done) {
choiceWidgetDict.set('Ff', 'readonly');
const choiceWidgetRef = new Ref(165, 0);
const choiceWidgetRef = Ref.get(165, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, }
]);
@ -1364,7 +1364,7 @@ describe('annotation', function() {
AnnotationFieldFlag.COMBO +
AnnotationFieldFlag.MULTISELECT);
const choiceWidgetRef = new Ref(512, 0);
const choiceWidgetRef = Ref.get(512, 0);
const xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, }
]);
@ -1387,7 +1387,7 @@ describe('annotation', function() {
lineDict.set('Subtype', Name.get('Line'));
lineDict.set('L', [1, 2, 3, 4]);
const lineRef = new Ref(122, 0);
const lineRef = Ref.get(122, 0);
const xref = new XRefMock([
{ ref: lineRef, data: lineDict, }
]);
@ -1415,20 +1415,20 @@ describe('annotation', function() {
const lexer = new Lexer(fileStream);
const parser = new Parser(lexer, /* allowStreams = */ true);
const fileStreamRef = new Ref(18, 0);
const fileStreamRef = Ref.get(18, 0);
const fileStreamDict = parser.getObj();
const embeddedFileDict = new Dict();
embeddedFileDict.set('F', fileStreamRef);
const fileSpecRef = new Ref(19, 0);
const fileSpecRef = Ref.get(19, 0);
const fileSpecDict = new Dict();
fileSpecDict.set('Type', Name.get('Filespec'));
fileSpecDict.set('Desc', '');
fileSpecDict.set('EF', embeddedFileDict);
fileSpecDict.set('UF', 'Test.txt');
const fileAttachmentRef = new Ref(20, 0);
const fileAttachmentRef = Ref.get(20, 0);
const fileAttachmentDict = new Dict();
fileAttachmentDict.set('Type', Name.get('Annot'));
fileAttachmentDict.set('Subtype', Name.get('FileAttachment'));
@ -1468,7 +1468,7 @@ describe('annotation', function() {
popupDict.set('Subtype', Name.get('Popup'));
popupDict.set('Parent', parentDict);
const popupRef = new Ref(13, 0);
const popupRef = Ref.get(13, 0);
const xref = new XRefMock([
{ ref: popupRef, data: popupDict, }
]);
@ -1492,7 +1492,7 @@ describe('annotation', function() {
popupDict.set('Subtype', Name.get('Popup'));
popupDict.set('Parent', parentDict);
const popupRef = new Ref(13, 0);
const popupRef = Ref.get(13, 0);
const xref = new XRefMock([
{ ref: popupRef, data: popupDict, }
]);
@ -1519,7 +1519,7 @@ describe('annotation', function() {
popupDict.set('F', 25); // not viewable
popupDict.set('Parent', parentDict);
const popupRef = new Ref(13, 0);
const popupRef = Ref.get(13, 0);
const xref = new XRefMock([
{ ref: popupRef, data: popupDict, }
]);
@ -1544,7 +1544,7 @@ describe('annotation', function() {
inkDict.set('Subtype', Name.get('Ink'));
inkDict.set('InkList', [[1, 1, 1, 2, 2, 2, 3, 3]]);
const inkRef = new Ref(142, 0);
const inkRef = Ref.get(142, 0);
const xref = new XRefMock([
{ ref: inkRef, data: inkDict, }
]);
@ -1572,7 +1572,7 @@ describe('annotation', function() {
[3, 3, 4, 5],
]);
const inkRef = new Ref(143, 0);
const inkRef = Ref.get(143, 0);
const xref = new XRefMock([
{ ref: inkRef, data: inkDict, }
]);

View File

@ -50,7 +50,7 @@ describe('colorspace', function () {
it('should handle the case when cs is a Name object', function () {
let cs = Name.get('DeviceGray');
let xref = new XRefMock([{
ref: new Ref(10, 0),
ref: Ref.get(10, 0),
data: new Dict(),
}]);
let res = new Dict();
@ -89,7 +89,7 @@ describe('colorspace', function () {
expect(testDest).toEqual(expectedDest);
});
it('should handle the case when cs is an indirect object', function () {
let cs = new Ref(10, 0);
let cs = Ref.get(10, 0);
let xref = new XRefMock([{
ref: cs,
data: Name.get('DeviceGray'),
@ -128,7 +128,7 @@ describe('colorspace', function () {
it('should handle the case when cs is a Name object', function () {
let cs = Name.get('DeviceRGB');
let xref = new XRefMock([{
ref: new Ref(10, 0),
ref: Ref.get(10, 0),
data: new Dict(),
}]);
let res = new Dict();
@ -172,7 +172,7 @@ describe('colorspace', function () {
expect(testDest).toEqual(expectedDest);
});
it('should handle the case when cs is an indirect object', function () {
let cs = new Ref(10, 0);
let cs = Ref.get(10, 0);
let xref = new XRefMock([{
ref: cs,
data: Name.get('DeviceRGB'),
@ -216,7 +216,7 @@ describe('colorspace', function () {
it('should handle the case when cs is a Name object', function () {
let cs = Name.get('DeviceCMYK');
let xref = new XRefMock([{
ref: new Ref(10, 0),
ref: Ref.get(10, 0),
data: new Dict(),
}]);
let res = new Dict();
@ -260,7 +260,7 @@ describe('colorspace', function () {
expect(testDest).toEqual(expectedDest);
});
it('should handle the case when cs is an indirect object', function () {
let cs = new Ref(10, 0);
let cs = Ref.get(10, 0);
let xref = new XRefMock([{
ref: cs,
data: Name.get('DeviceCMYK'),
@ -312,7 +312,7 @@ describe('colorspace', function () {
params,
];
let xref = new XRefMock([{
ref: new Ref(10, 0),
ref: Ref.get(10, 0),
data: new Dict(),
}]);
let res = new Dict();
@ -365,7 +365,7 @@ describe('colorspace', function () {
params,
];
let xref = new XRefMock([{
ref: new Ref(10, 0),
ref: Ref.get(10, 0),
data: new Dict(),
}]);
let res = new Dict();
@ -415,7 +415,7 @@ describe('colorspace', function () {
params,
];
let xref = new XRefMock([{
ref: new Ref(10, 0),
ref: Ref.get(10, 0),
data: new Dict(),
}]);
let res = new Dict();
@ -468,7 +468,7 @@ describe('colorspace', function () {
lookup,
];
let xref = new XRefMock([{
ref: new Ref(10, 0),
ref: Ref.get(10, 0),
data: new Dict(),
}]);
let res = new Dict();
@ -515,7 +515,7 @@ describe('colorspace', function () {
'exch 0.21 mul }');
fn = new Stream(fn.bytes, 0, 58, fnDict);
let fnRef = new Ref(10, 0);
let fnRef = Ref.get(10, 0);
let cs = [
Name.get('Separation'),

View File

@ -42,7 +42,7 @@ describe('core_utils', function() {
});
it('fetches the property if it is not inherited', function() {
const ref = new Ref(10, 0);
const ref = Ref.get(10, 0);
const xref = new XRefMock([{ ref, data: 'quux', }]);
const dict = new Dict(xref);
@ -58,7 +58,7 @@ describe('core_utils', function() {
it('fetches the property if it is inherited and present on one level',
function() {
const ref = new Ref(10, 0);
const ref = Ref.get(10, 0);
const xref = new XRefMock([{ ref, data: 'quux', }]);
const firstDict = new Dict(xref);
const secondDict = new Dict(xref);
@ -78,7 +78,7 @@ describe('core_utils', function() {
it('fetches the property if it is inherited and present on multiple levels',
function() {
const ref = new Ref(10, 0);
const ref = Ref.get(10, 0);
const xref = new XRefMock([{ ref, data: 'quux', }]);
const firstDict = new Dict(xref);
const secondDict = new Dict(xref);

View File

@ -185,7 +185,7 @@ describe('primitives', function() {
it('should handle keys pointing to indirect objects, both sync and async',
function (done) {
var fontRef = new Ref(1, 0);
var fontRef = Ref.get(1, 0);
var xref = new XRefMock([
{ ref: fontRef, data: testFontFile, }
]);
@ -206,7 +206,7 @@ describe('primitives', function() {
});
it('should handle arrays containing indirect objects', function () {
var minCoordRef = new Ref(1, 0), maxCoordRef = new Ref(2, 0);
var minCoordRef = Ref.get(1, 0), maxCoordRef = Ref.get(2, 0);
var minCoord = 0, maxCoord = 1;
var xref = new XRefMock([
{ ref: minCoordRef, data: minCoord, },
@ -254,7 +254,7 @@ describe('primitives', function() {
it('should retain the stored values', function() {
var storedNum = 4;
var storedGen = 2;
var ref = new Ref(storedNum, storedGen);
var ref = Ref.get(storedNum, storedGen);
expect(ref.num).toEqual(storedNum);
expect(ref.gen).toEqual(storedGen);
});
@ -262,18 +262,18 @@ describe('primitives', function() {
describe('RefSet', function() {
it('should have a stored value', function() {
var ref = new Ref(4, 2);
var ref = Ref.get(4, 2);
var refset = new RefSet();
refset.put(ref);
expect(refset.has(ref)).toBeTruthy();
});
it('should not have an unknown value', function() {
var ref = new Ref(4, 2);
var ref = Ref.get(4, 2);
var refset = new RefSet();
expect(refset.has(ref)).toBeFalsy();
refset.put(ref);
var anotherRef = new Ref(2, 4);
var anotherRef = Ref.get(2, 4);
expect(refset.has(anotherRef)).toBeFalsy();
});
});
@ -341,21 +341,21 @@ describe('primitives', function() {
});
it('handles refs', function () {
var ref = new Ref(1, 0);
var ref = Ref.get(1, 0);
expect(isRef(ref)).toEqual(true);
});
});
describe('isRefsEqual', function () {
it('should handle different Refs pointing to the same object', function () {
var ref1 = new Ref(1, 0);
var ref2 = new Ref(1, 0);
it('should handle Refs pointing to the same object', function () {
var ref1 = Ref.get(1, 0);
var ref2 = Ref.get(1, 0);
expect(isRefsEqual(ref1, ref2)).toEqual(true);
});
it('should handle Refs pointing to different objects', function () {
var ref1 = new Ref(1, 0);
var ref2 = new Ref(2, 0);
var ref1 = Ref.get(1, 0);
var ref2 = Ref.get(2, 0);
expect(isRefsEqual(ref1, ref2)).toEqual(false);
});
});