Skip to content

Commit

Permalink
Fix issue mozilla#5026
Browse files Browse the repository at this point in the history
  • Loading branch information
fkaelberer committed Aug 1, 2014
1 parent aaae640 commit 015c595
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: node_js
node_js:
- 0.10
- "0.10"
53 changes: 43 additions & 10 deletions src/core/cmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ var CMap = (function CMapClosure() {
// where nBytePairs are ranges e.g. [low1, high1, low2, high2, ...]
this.codespaceRanges = [[], [], [], []];
this.numCodespaceRanges = 0;
this.map = [];
this._map = [];
this.vertical = false;
this.useCMap = null;
this.builtInCMap = builtInCMap;
Expand All @@ -213,7 +213,7 @@ var CMap = (function CMapClosure() {
mapRange: function(low, high, dstLow) {
var lastByte = dstLow.length - 1;
while (low <= high) {
this.map[low] = dstLow;
this._map[low] = dstLow;
// Only the last byte has to be incremented.
dstLow = dstLow.substr(0, lastByte) +
String.fromCharCode(dstLow.charCodeAt(lastByte) + 1);
Expand All @@ -224,17 +224,51 @@ var CMap = (function CMapClosure() {
mapRangeToArray: function(low, high, array) {
var i = 0, ii = array.length;
while (low <= high && i < ii) {
this.map[low] = array[i++];
this._map[low] = array[i++];
++low;
}
},

mapOne: function(src, dst) {
this.map[src] = dst;
this._map[src] = dst;
},

lookup: function(code) {
return this.map[code];
return this._map[code];
},

contains: function(code) {
return this._map[code] !== undefined;
},

forEach: function(callback) {
// Most maps have fewer than 65536 entries, and for those we use normal
// array iteration. But really sparse tables are possible -- e.g. with
// indices in the *billions*. For such tables we use for..in, which isn't
// ideal because it stringifies the indices for all present elements, but
// it does avoid iterating over every undefined entry.
var map = this._map;
var length = map.length;
var i;
if (length <= 0x10000) {
for (i = 0; i < length; i++) {
if (map[i] !== undefined) {
callback(i, map[i]);
}
}
} else {
for (i in this._map) {
callback(i, map[i]);
}
}
},

charCodeOf: function(value) {
return this._map.indexOf(value);
},

getMap: function() {
return this._map;
},

readCharCode: function(str, offset) {
Expand Down Expand Up @@ -789,12 +823,11 @@ var CMapFactory = (function CMapFactoryClosure() {
}
// Merge the map into the current one, making sure not to override
// any previously defined entries.
for (var key in cMap.useCMap.map) {
if (key in cMap.map) {
continue;
cMap.useCMap.forEach(function(key, value) {
if (!cMap.contains(key)) {
cMap.mapOne(key, cMap.useCMap.lookup(key));
}
cMap.map[key] = cMap.useCMap.map[key];
}
});
}

function parseBinaryCMap(name, builtInCMapParams) {
Expand Down
4 changes: 2 additions & 2 deletions src/core/evaluator.js
Original file line number Diff line number Diff line change
Expand Up @@ -1309,10 +1309,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var cmapObj = toUnicode;
if (isName(cmapObj)) {
return CMapFactory.create(cmapObj,
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).map;
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap();
} else if (isStream(cmapObj)) {
var cmap = CMapFactory.create(cmapObj,
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).map;
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null).getMap();
// Convert UTF-16BE
// NOTE: cmap can be a sparse array, so use forEach instead of for(;;)
// to iterate over all keys.
Expand Down
32 changes: 14 additions & 18 deletions src/core/fonts.js
Original file line number Diff line number Diff line change
Expand Up @@ -3898,10 +3898,7 @@ var Font = (function FontClosure() {
if (properties.type === 'CIDFontType2') {
var cidToGidMap = properties.cidToGidMap || [];
var cidToGidMapLength = cidToGidMap.length;
var cMap = properties.cMap.map;
for (charCode in cMap) {
charCode |= 0;
var cid = cMap[charCode];
properties.cMap.forEach(function(charCode, cid) {
assert(cid.length === 1, 'Max size of CID is 65,535');
cid = cid.charCodeAt(0);
var glyphId = -1;
Expand All @@ -3913,7 +3910,7 @@ var Font = (function FontClosure() {
if (glyphId >= 0 && glyphId < numGlyphs) {
charCodeToGlyphId[charCode] = glyphId;
}
}
});
if (dupFirstEntry) {
charCodeToGlyphId[0] = numGlyphs - 1;
}
Expand Down Expand Up @@ -3971,7 +3968,7 @@ var Font = (function FontClosure() {
if (!found && properties.glyphNames) {
// Try to map using the post table. There are currently no known
// pdfs that this fixes.
glyphId = properties.glyphNames.indexOf(glyphName);
var glyphId = properties.glyphNames.indexOf(glyphName);
if (glyphId > 0) {
charCodeToGlyphId[charCode] = glyphId;
}
Expand Down Expand Up @@ -4372,18 +4369,17 @@ var Font = (function FontClosure() {
{ url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null);
var cMap = properties.cMap;
toUnicode = [];
for (charcode in cMap.map) {
var cid = cMap.map[charcode];
cMap.forEach(function(charcode, cid) {
assert(cid.length === 1, 'Max size of CID is 65,535');
// e) Map the CID obtained in step (a) according to the CMap obtained
// in step (d), producing a Unicode value.
var ucs2 = ucs2CMap.map[cid.charCodeAt(0)];
if (!ucs2) {
continue;
var ucs2 = ucs2CMap.lookup(cid.charCodeAt(0));
if (ucs2) {
toUnicode[charcode] =
String.fromCharCode((ucs2.charCodeAt(0) << 8) +
ucs2.charCodeAt(1));
}
toUnicode[charcode] = String.fromCharCode((ucs2.charCodeAt(0) << 8) +
ucs2.charCodeAt(1));
}
});
map.toUnicode = toUnicode;
return map;
}
Expand Down Expand Up @@ -4418,7 +4414,7 @@ var Font = (function FontClosure() {
// finding the charcode via unicodeToCID map
var charcode = 0;
if (this.composite) {
if (glyphUnicode in this.cMap.map) {
if (this.cMap.contains(glyphUnicode)) {
charcode = this.cMap.lookup(glyphUnicode).charCodeAt(0);
}
}
Expand Down Expand Up @@ -4447,8 +4443,8 @@ var Font = (function FontClosure() {
var fontCharCode, width, operatorListId;

var widthCode = charcode;
if (this.cMap && charcode in this.cMap.map) {
widthCode = this.cMap.map[charcode].charCodeAt(0);
if (this.cMap && this.cMap.contains(charcode)) {
widthCode = this.cMap.lookup(charcode).charCodeAt(0);
}
width = this.widths[widthCode];
width = isNum(width) ? width : this.defaultWidth;
Expand Down Expand Up @@ -5631,7 +5627,7 @@ var CFFFont = (function CFFFontClosure() {
// to map CIDs to GIDs.
for (glyphId = 0; glyphId < charsets.length; glyphId++) {
var cidString = String.fromCharCode(charsets[glyphId]);
var charCode = properties.cMap.map.indexOf(cidString);
var charCode = properties.cMap.charCodeOf(cidString);
charCodeToGlyphId[charCode] = glyphId;
}
} else {
Expand Down
10 changes: 6 additions & 4 deletions src/core/jbig2.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
];

var ReusedContexts = [
0x1CD3, // '00111001101' (template) + '0011' (at),
0x3953, // '001110010101' (template) + '0011' (at),
0x079A, // '001111001101' + '0',
0x00E3, // '001110001' + '1',
0x018B // '011000101' + '1'
Expand All @@ -165,9 +165,11 @@ var Jbig2Image = (function Jbig2ImageClosure() {
// Sorting is non-standard, and it is not required. But sorting increases
// the number of template bits that can be reused from the previous
// contextLabel in the main loop.
template.sort(function (a, b) {
return (a.y - b.y) || (a.x - b.x);
});
if (!prediction) {
template.sort(function (a, b) {
return (a.y - b.y) || (a.x - b.x);
});
}

var templateLength = template.length;
var templateX = new Int8Array(templateLength);
Expand Down
3 changes: 3 additions & 0 deletions test/pdfs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
!issue918.pdf
!issue1905.pdf
!issue2833.pdf
!issue2931.pdf
!issue3323.pdf
!issue4304.pdf
!issue4550.pdf
!rotated.pdf
!issue1249.pdf
Expand Down
Binary file added test/pdfs/issue2931.pdf
Binary file not shown.
Binary file added test/pdfs/issue3323.pdf
Binary file not shown.
Binary file added test/pdfs/issue4304.pdf
Binary file not shown.
21 changes: 21 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,27 @@
"link": true,
"type": "eq"
},
{ "id": "issue2931",
"file": "pdfs/issue2931.pdf",
"md5": "ea40940eaf3541b312bda9329167da11",
"link": false,
"rounds": 1,
"type": "eq"
},
{ "id": "issue3323",
"file": "pdfs/issue3323.pdf",
"md5": "1a14ff574013caeafa9d598269988764",
"link": false,
"rounds": 1,
"type": "eq"
},
{ "id": "issue4304",
"file": "pdfs/issue4304.pdf",
"md5": "1b1205bf0d7c1ad22a154b60da8e694d",
"link": false,
"rounds": 1,
"type": "eq"
},
{ "id": "zerowidthline",
"file": "pdfs/zerowidthline.pdf",
"md5": "295d26e61a85635433f8e4b768953f60",
Expand Down

0 comments on commit 015c595

Please sign in to comment.