var strings = this.getStrings(stringIndex);
- var baseDict = this.parseDict(dictIndex.get(0));
+ var baseDict = this.parseDict(dictIndex.get(0).data);
var topDict = this.getTopDict(baseDict, strings);
var bytes = this.bytes;
if (hasSupplement)
bytes[topDict.Encoding] = 0;
+ // The CFF specification state that the 'dotsection' command
+ // (12, 0) is deprecated and treated as a no-op, but all Type2
+ // charstrings processors should support them. Unfortunately
+ // the font sanitizer don't. As a workaround the sequence (12, 0)
+ // is replaced by a useless (0, hmoveto).
+ var count = charStrings.length;
+ for (var i = 0; i < count; i++) {
+ var charstring = charStrings.get(i);
+
+ var start = charstring.start;
+ var data = charstring.data;
+ var length = data.length;
+ for (var j = 0; j <= length; j) {
+ var value = data[j++];
+ if (value == 12 && data[j++] == 0) {
+ bytes[start + j - 2] = 139;
+ bytes[start + j - 1] = 22;
+ } else if (value === 28) {
+ j += 2;
+ } else if (value >= 247 && value <= 254) {
+ j++;
+ } else if (value == 255) {
+ j += 4;
+ }
+ }
+ }
+
// charstrings contains info about glyphs (one element per glyph
// containing mappings for {unicode, width})
var charstrings = this.getCharStrings(charset, charStrings,
} else if (value <= 254) {
return -((value - 251) * 256) - dict[pos++] - 108;
} else {
- error('Incorrect byte');
+ error('255 is not a valid DICT command');
}
return -1;
};
var start = offsets[index];
var end = offsets[index + 1];
- return bytes.subarray(start, end);
+ return {
+ start: start,
+ end: end,
+ data: bytes.subarray(start, end)
+ }
},
length: count,
endPos: end
var charset = {};
var format = aStream.getByte();
+ var count = aCharstrings.length - 1;
if (format == 0) {
charset['.notdef'] = readCharstringEncoding(aCharstrings[0]);
- var count = aCharstrings.length - 1;
for (var i = 1; i < count + 1; i++) {
var sid = aStream.getByte() << 8 | aStream.getByte();
charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]);
//log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]);
}
} else if (format == 1) {
- error('Charset Range are not supported');
+ for (var i = 1; i < count + 1; i++) {
+ var first = aStream.getByte();
+ first = (first << 8) | aStream.getByte();
+ var numLeft = aStream.getByte();
+ for (var j = 0; j <= numLeft; j++) {
+ var sid = first++;
+ if (CFFStrings[sid] == 'three')
+ log(aCharstrings[j]);
+ charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[j]);
+ }
+ }
} else {
error('Invalid charset format');
}
* chapter 3.1.
*/
function readCharstringEncoding(aString) {
+ if (!aString)
+ return "";
+
var charstringTokens = [];
var count = aString.length;
} else if (value < 247) {
token = parseInt(value) - 139;
} else if (value < 251) {
- token = ((value - 247) * 256) + aString[i++] + 108;
+ token = (value - 247) * 256 + aString[i++] + 108;
} else if (value < 255) {
- token = -((value - 251) * 256) - aString[i++] - 108;
+ token = -(value - 251) * 256 - aString[i++] - 108;
} else {// value == 255
token = aString[i++] << 24 | aString[i++] << 16 |
aString[i++] << 8 | aString[i];
} else if (value <= 246) {
token = parseInt(value) - 139;
} else if (value <= 250) {
- token = ((value - 247) * 256) + aString[i++] + 108;
+ token = (value - 247) * 256 + aString[i++] + 108;
} else if (value <= 254) {
- token = -((value - 251) * 256) - aString[i++] - 108;
+ token = -(value - 251) * 256 - aString[i++] - 108;
} else if (value == 255) {
error('255 is not a valid DICT command');
}
for (var i = 0; i < count + 1; i++)
offsets.push(getNextOffset());
- log('Found ' + count + ' objects at offsets :' +
+ dump('Found ' + count + ' objects at offsets :' +
offsets + ' (offsize: ' + offsize + ')');
// Now extract the objects
font.set('hdrSize', aStream.getByte());
font.set('offsize', aStream.getByte());
- // Move the cursor after the header
- aStream.skip(font.get('hdrSize') - aStream.pos);
-
// Read the NAME Index
dump('Reading Index: Names');
font.set('Names', readFontIndexData(aStream));
- log('Names: ' + font.get('Names'));
+ dump('Names: ' + font.get('Names'));
// Read the Top Dict Index
dump('Reading Index: TopDict');
var topDict = readFontIndexData(aStream, true);
- log('TopDict: ' + topDict);
+ dump('TopDict: ' + topDict);
// Read the String Index
dump('Reading Index: Strings');
var strings = readFontIndexData(aStream);
- log('strings: ' + strings);
+ dump('strings: ' + strings);
// Fill up the Strings dictionary with the new unique strings
for (var i = 0; i < strings.length; i++)
// Reading Private Dict
var priv = font.get('Private');
- log('Reading Private Dict (offset: ' + priv.offset +
+ dump('Reading Private Dict (offset: ' + priv.offset +
' size: ' + priv.size + ')');
aStream.pos = priv.offset;