Make IdentityCMaps more compact.
IdentityCMap uses an array to represent a 16-bit unsigned identity function. This is very space-inefficient, and some files cause multiple IdentityCMaps to be instantiated (e.g. the one from #4580 has 74). This patch make the representation implicit. When loading the PDF from issue #4580, this change reduces peak RSS from ~370 to ~280 MiB. It also improves overall speed on that PDF by ~30%, going from 522 ms to 366 ms.
This commit is contained in:
parent
6865c284a7
commit
51055e5836
@ -302,20 +302,69 @@ var CMap = (function CMapClosure() {
|
|||||||
|
|
||||||
return [0, 1];
|
return [0, 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
return CMap;
|
return CMap;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// A special case of CMap, where the _map array implicitly has a length of
|
||||||
|
// 65535 and each element is equal to its index.
|
||||||
var IdentityCMap = (function IdentityCMapClosure() {
|
var IdentityCMap = (function IdentityCMapClosure() {
|
||||||
function IdentityCMap(vertical, n) {
|
function IdentityCMap(vertical, n) {
|
||||||
CMap.call(this);
|
CMap.call(this);
|
||||||
this.vertical = vertical;
|
this.vertical = vertical;
|
||||||
this.addCodespaceRange(n, 0, 0xffff);
|
this.addCodespaceRange(n, 0, 0xffff);
|
||||||
this.mapCidRange(0, 0xffff, 0);
|
|
||||||
}
|
}
|
||||||
Util.inherit(IdentityCMap, CMap, {});
|
Util.inherit(IdentityCMap, CMap, {});
|
||||||
|
|
||||||
|
IdentityCMap.prototype = {
|
||||||
|
addCodespaceRange: CMap.prototype.addCodespaceRange,
|
||||||
|
|
||||||
|
mapCidRange: function(low, high, dstLow) {
|
||||||
|
error('should not call mapCidRange');
|
||||||
|
},
|
||||||
|
|
||||||
|
mapBfRange: function(low, high, dstLow) {
|
||||||
|
error('should not call mapBfRange');
|
||||||
|
},
|
||||||
|
|
||||||
|
mapBfRangeToArray: function(low, high, array) {
|
||||||
|
error('should not call mapBfRangeToArray');
|
||||||
|
},
|
||||||
|
|
||||||
|
mapOne: function(src, dst) {
|
||||||
|
error('should not call mapCidOne');
|
||||||
|
},
|
||||||
|
|
||||||
|
lookup: function(code) {
|
||||||
|
return (isInt(code) && code <= 0xffff) ? code : undefined;
|
||||||
|
},
|
||||||
|
|
||||||
|
contains: function(code) {
|
||||||
|
return isInt(code) && code <= 0xffff;
|
||||||
|
},
|
||||||
|
|
||||||
|
forEach: function(callback) {
|
||||||
|
for (var i = 0; i <= 0xffff; i++) {
|
||||||
|
callback(i, i);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
charCodeOf: function(value) {
|
||||||
|
return (isInt(value) && value <= 0xffff) ? value : -1;
|
||||||
|
},
|
||||||
|
|
||||||
|
getMap: function() {
|
||||||
|
// Sometimes identity maps must be instantiated, but it's rare.
|
||||||
|
var map = new Array(0x10000);
|
||||||
|
for (var i = 0; i <= 0xffff; i++) {
|
||||||
|
map[i] = i;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
},
|
||||||
|
|
||||||
|
readCharCode: CMap.prototype.readCharCode
|
||||||
|
};
|
||||||
|
|
||||||
return IdentityCMap;
|
return IdentityCMap;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user