Support Type1C built-in encoding - part1

This commit is contained in:
Vivien Nicolas 2011-08-30 19:52:24 +02:00
parent a417271628
commit 395a46c85e

View File

@ -1019,9 +1019,8 @@ var Font = (function Font() {
var glyphs = []; var glyphs = [];
var encoding = properties.encoding; var encoding = properties.encoding;
for (var i = 1; i < numGlyphs; i++) { for (var i = 1; i < numGlyphs; i++)
glyphs.push({ unicode: i + kCmapGlyphOffset }); glyphs.push({ unicode: i + kCmapGlyphOffset });
}
if ('undefined' == typeof(encoding[0])) { if ('undefined' == typeof(encoding[0])) {
// the font is directly characters to glyphs with no encoding // the font is directly characters to glyphs with no encoding
@ -2133,7 +2132,6 @@ CFF.prototype = {
}; };
var Type2CFF = (function() { var Type2CFF = (function() {
// TODO: replace parsing code with the Type2Parser in font_utils.js // TODO: replace parsing code with the Type2Parser in font_utils.js
function constructor(file, properties) { function constructor(file, properties) {
var bytes = file.getBytes(); var bytes = file.getBytes();
@ -2146,11 +2144,11 @@ var Type2CFF = (function() {
data.push(bytes[i]); data.push(bytes[i]);
this.data = data; this.data = data;
this.parse(); this.parse(properties);
}; };
constructor.prototype = { constructor.prototype = {
parse: function cff_parse() { parse: function cff_parse(properties) {
var header = this.parseHeader(); var header = this.parseHeader();
var nameIndex = this.parseIndex(header.endPos); var nameIndex = this.parseIndex(header.endPos);
@ -2174,26 +2172,25 @@ var Type2CFF = (function() {
baseDict = this.parseDict(privBytes); baseDict = this.parseDict(privBytes);
var privDict = this.getPrivDict(baseDict, strings); var privDict = this.getPrivDict(baseDict, strings);
TODO('Parse encoding');
var charStrings = this.parseIndex(topDict['CharStrings']); var charStrings = this.parseIndex(topDict['CharStrings']);
var charset = this.parseCharsets(topDict['charset'], charStrings.length, var charset = this.parseCharsets(topDict['charset'], charStrings.length, strings);
strings); var encoding = this.parseEncoding(topDict['Encoding'], properties, strings, charset);
// charstrings contains info about glyphs (one element per glyph // charstrings contains info about glyphs (one element per glyph
// containing mappings for {unicode, width}) // containing mappings for {unicode, width})
var charstrings = this.getCharStrings(charset, charStrings, var charstrings = this.getCharStrings(charset, charStrings, encoding,
privDict, this.properties); privDict, this.properties);
// create the mapping between charstring and glyph id // create the mapping between charstring and glyph id
var glyphIds = []; var glyphIds = [];
for (var i = 0, ii = charstrings.length; i < ii; ++i) { for (var i = 0; i < charstrings.length; i++)
glyphIds.push(charstrings[i].gid); glyphIds.push(charstrings[i].gid);
}
this.charstrings = charstrings; this.charstrings = charstrings;
this.glyphIds = glyphIds; this.glyphIds = glyphIds;
}, },
getCharStrings: function cff_charstrings(charsets, charStrings,
getCharStrings: function cff_charstrings(charsets, charStrings, encoding,
privDict, properties) { privDict, properties) {
var widths = properties.widths; var widths = properties.widths;
@ -2201,31 +2198,75 @@ var Type2CFF = (function() {
var nominalWidth = privDict['nominalWidthX']; var nominalWidth = privDict['nominalWidthX'];
var charstrings = []; var charstrings = [];
for (var i = 0, ii = charsets.length; i < ii; ++i) { for (var code in encoding) {
var charName = charsets[i]; var gid = encoding[code];
var charCode = properties.glyphs[charName]; var width = widths[code] || defaultWidth;
if (charCode) { charstrings.push({unicode: code, width: width, gid: gid});
var width = widths[charCode] || defaultWidth;
charstrings.push({unicode: charCode, width: width, gid: i});
} else {
if (charName !== '.notdef')
warn('Cannot find unicode for glyph ' + charName);
}
} }
// sort the arry by the unicode value // sort the array by the unicode value
charstrings.sort(function(a, b) {return a.unicode - b.unicode}); charstrings.sort(function(a, b) {return a.unicode - b.unicode});
return charstrings; return charstrings;
}, },
parseEncoding: function cff_parseencoding(pos) {
if (pos == 0) { parseEncoding: function cff_parseencoding(pos, properties, strings, charset) {
return Encodings.StandardEncoding; var encoding = {};
} else if (pos == 1) { var bytes = this.bytes;
return Encodings.ExpertEncoding;
function readSupplement() {
var supplementsCount = bytes[pos++];
for (var i = 0; i < supplementsCount; i++) {
var code = bytes[pos++];
var sid = (bytes[pos++] << 8) + (bytes[pos++] & 0xff);
encoding[code] = properties.differences.indexOf(strings[sid]);
}
} }
error('not implemented encodings'); if (pos == 0 || pos == 1) {
var gid = 1;
var baseEncoding = pos ? Encodings.ExpertEncoding
: Encodings.StandardEncoding;
for (var i = 0; i < charset.length; i++) {
var index = baseEncoding.indexOf(charset[i]);
if (index != -1)
encoding[index] = gid++;
}
} else {
var format = bytes[pos++];
switch (format & 0x7f) {
case 0:
var glyphsCount = bytes[pos++];
for (var i = 1; i <= glyphsCount; i++)
encoding[bytes[pos++]] = i;
if (format & 0x80)
readSupplement();
break;
case 1:
var rangesCount = bytes[pos++];
log(rangesCount);
var gid = 1;
for (var i = 0; i < rangesCount; i++) {
var start = bytes[pos++];
var count = bytes[pos++];
for (var j = start; j <= start + count; j++)
encoding[j] = gid++;
}
if (format & 0x80)
readSupplement();
break;
default:
error('Unknow encoding format: ' + format + " in CFF");
break;
}
}
return encoding;
}, },
parseCharsets: function cff_parsecharsets(pos, length, strings) { parseCharsets: function cff_parsecharsets(pos, length, strings) {
var bytes = this.bytes; var bytes = this.bytes;
var format = bytes[pos++]; var format = bytes[pos++];