Open the CFF class road for Type1C font
This commit is contained in:
parent
2e7df01459
commit
5cbc6875b3
134
fonts.js
134
fonts.js
@ -6,7 +6,7 @@
|
|||||||
/**
|
/**
|
||||||
* Maximum file size of the font.
|
* Maximum file size of the font.
|
||||||
*/
|
*/
|
||||||
var kMaxFontFileSize = 40000;
|
var kMaxFontFileSize = 200000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum time to wait for a font to be loaded by @font-face
|
* Maximum time to wait for a font to be loaded by @font-face
|
||||||
@ -34,7 +34,7 @@ var kDisableFonts = false;
|
|||||||
* http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65
|
* http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Fonts = (function () {
|
var Fonts = (function Fonts() {
|
||||||
var kScalePrecision = 40;
|
var kScalePrecision = 40;
|
||||||
var fonts = Object.create(null);
|
var fonts = Object.create(null);
|
||||||
var ctx = document.createElement("canvas").getContext("2d");
|
var ctx = document.createElement("canvas").getContext("2d");
|
||||||
@ -1462,13 +1462,17 @@ var CFF = function(name, file, properties) {
|
|||||||
var length1 = file.dict.get("Length1");
|
var length1 = file.dict.get("Length1");
|
||||||
var length2 = file.dict.get("Length2");
|
var length2 = file.dict.get("Length2");
|
||||||
file.skip(length1);
|
file.skip(length1);
|
||||||
var eexecBlock = file.getBytes(length2);
|
|
||||||
|
|
||||||
// Decrypt the data blocks and retrieve it's content
|
// Decrypt the data blocks and retrieve it's content
|
||||||
|
var eexecBlock = file.getBytes(length2);
|
||||||
var data = type1Parser.extractFontProgram(eexecBlock);
|
var data = type1Parser.extractFontProgram(eexecBlock);
|
||||||
|
|
||||||
this.charstrings = this.getOrderedCharStrings(data.charstrings);
|
var charstrings = this.getOrderedCharStrings(data.charstrings);
|
||||||
this.data = this.wrap(name, this.charstrings, data.subrs, properties);
|
var type2Charstrings = this.getType2Charstrings(charstrings);
|
||||||
|
var subrs = this.getType2Subrs(data.subrs);
|
||||||
|
|
||||||
|
this.charstrings = charstrings;
|
||||||
|
this.data = this.wrap(name, type2Charstrings, this.charstrings, subrs, properties);
|
||||||
};
|
};
|
||||||
|
|
||||||
CFF.prototype = {
|
CFF.prototype = {
|
||||||
@ -1546,12 +1550,40 @@ CFF.prototype = {
|
|||||||
return charstrings;
|
return charstrings;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getType2Charstrings: function cff_getType2Charstrings(type1Charstrings) {
|
||||||
|
var type2Charstrings = [];
|
||||||
|
var count = type1Charstrings.length;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
var charstring = type1Charstrings[i].charstring;
|
||||||
|
type2Charstrings.push(this.flattenCharstring(charstring.slice(), this.commandsMap));
|
||||||
|
}
|
||||||
|
return type2Charstrings;
|
||||||
|
},
|
||||||
|
|
||||||
|
getType2Subrs: function cff_getType2Charstrings(type1Subrs) {
|
||||||
|
var bias = 0;
|
||||||
|
var count = type1Subrs.length;
|
||||||
|
if (count < 1240)
|
||||||
|
bias = 107;
|
||||||
|
else if (count < 33900)
|
||||||
|
bias = 1131;
|
||||||
|
else
|
||||||
|
bias = 32768;
|
||||||
|
|
||||||
|
// Add a bunch of empty subrs to deal with the Type2 bias
|
||||||
|
var type2Subrs = [];
|
||||||
|
for (var i = 0; i < bias; i++)
|
||||||
|
type2Subrs.push([0x0B]);
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
type2Subrs.push(this.flattenCharstring(type1Subrs[i], this.commandsMap));
|
||||||
|
|
||||||
|
return type2Subrs;
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flatten the commands by interpreting the postscript code and replacing
|
* Flatten the commands by interpreting the postscript code and replacing
|
||||||
* every 'callsubr', 'callothersubr' by the real commands.
|
* every 'callsubr', 'callothersubr' by the real commands.
|
||||||
*
|
|
||||||
* TODO This function also do a string to command number transformation
|
|
||||||
* that can probably be avoided if the Type1 decodeCharstring code is smarter
|
|
||||||
*/
|
*/
|
||||||
commandsMap: {
|
commandsMap: {
|
||||||
"hstem": 1,
|
"hstem": 1,
|
||||||
@ -1573,58 +1605,27 @@ CFF.prototype = {
|
|||||||
"hvcurveto": 31,
|
"hvcurveto": 31,
|
||||||
},
|
},
|
||||||
|
|
||||||
flattenCharstring: function flattenCharstring(charstring) {
|
flattenCharstring: function flattenCharstring(charstring, map) {
|
||||||
var i = 0;
|
for (var i = 0; i < charstring.length; i++) {
|
||||||
while (true) {
|
var command = charstring[i];
|
||||||
var obj = charstring[i];
|
if (command.charAt) {
|
||||||
if (obj == undefined) {
|
var cmd = map[command];
|
||||||
error("unknow charstring command for " + i + " in " + charstring);
|
assert(cmd, "Unknow command: " + command);
|
||||||
}
|
|
||||||
if (obj.charAt) {
|
|
||||||
switch (obj) {
|
|
||||||
case "endchar":
|
|
||||||
case "return":
|
|
||||||
// CharString is ready to be re-encode to commands number at this point
|
|
||||||
for (var j = 0; j < charstring.length; j++) {
|
|
||||||
var command = charstring[j];
|
|
||||||
if (parseFloat(command) == command) {
|
|
||||||
charstring.splice(j, 1, 28, command >> 8, command);
|
|
||||||
j+= 2;
|
|
||||||
} else if (command.charAt) {
|
|
||||||
var cmd = this.commandsMap[command];
|
|
||||||
if (!cmd)
|
|
||||||
error("Unknow command: " + command);
|
|
||||||
|
|
||||||
if (IsArray(cmd)) {
|
if (IsArray(cmd)) {
|
||||||
charstring.splice(j, 1, cmd[0], cmd[1]);
|
charstring.splice(i++, 1, cmd[0], cmd[1]);
|
||||||
j += 1;
|
} else {
|
||||||
} else {
|
charstring[i] = cmd;
|
||||||
charstring[j] = cmd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return charstring;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
charstring.splice(i, 1, 28, command >> 8, command & 0xff);
|
||||||
|
i+= 2;
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
error("failing with i = " + i + " in charstring:" + charstring + "(" + charstring.length + ")");
|
return charstring;
|
||||||
return [];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
wrap: function wrap(name, charstrings, subrs, properties) {
|
wrap: function wrap(name, glyphs, charstrings, subrs, properties) {
|
||||||
// Starts the conversion of the Type1 charstrings to Type2
|
|
||||||
var glyphs = [];
|
|
||||||
var glyphsCount = charstrings.length;
|
|
||||||
for (var i = 0; i < glyphsCount; i++) {
|
|
||||||
var charstring = charstrings[i].charstring;
|
|
||||||
glyphs.push(this.flattenCharstring(charstring.slice()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a CFF font data
|
|
||||||
var cff = new Uint8Array(kMaxFontFileSize);
|
var cff = new Uint8Array(kMaxFontFileSize);
|
||||||
var currentOffset = 0;
|
var currentOffset = 0;
|
||||||
|
|
||||||
@ -1656,10 +1657,12 @@ CFF.prototype = {
|
|||||||
|
|
||||||
// Fill the charset header (first byte is the encoding)
|
// Fill the charset header (first byte is the encoding)
|
||||||
var charset = [0x00];
|
var charset = [0x00];
|
||||||
|
var glyphsCount = glyphs.length;
|
||||||
for (var i = 0; i < glyphsCount; i++) {
|
for (var i = 0; i < glyphsCount; i++) {
|
||||||
var index = CFFStrings.indexOf(charstrings[i].glyph);
|
var index = CFFStrings.indexOf(charstrings[i].glyph);
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
index = CFFStrings.length + strings.indexOf(charstrings[i].glyph);
|
index = CFFStrings.length + strings.indexOf(charstrings[i].glyph);
|
||||||
|
|
||||||
var bytes = FontsUtils.integerToBytes(index, 2);
|
var bytes = FontsUtils.integerToBytes(index, 2);
|
||||||
charset.push(bytes[0]);
|
charset.push(bytes[0]);
|
||||||
charset.push(bytes[1]);
|
charset.push(bytes[1]);
|
||||||
@ -1731,28 +1734,9 @@ CFF.prototype = {
|
|||||||
cff.set(privateData, currentOffset);
|
cff.set(privateData, currentOffset);
|
||||||
currentOffset += privateData.length;
|
currentOffset += privateData.length;
|
||||||
|
|
||||||
// Local Subrs
|
|
||||||
var flattenedSubrs = [];
|
|
||||||
|
|
||||||
var bias = 0;
|
// Local subrs
|
||||||
var subrsCount = subrs.length;
|
var subrsData = this.createCFFIndexHeader(subrs, true);
|
||||||
if (subrsCount < 1240)
|
|
||||||
bias = 107;
|
|
||||||
else if (subrsCount < 33900)
|
|
||||||
bias = 1131;
|
|
||||||
else
|
|
||||||
bias = 32768;
|
|
||||||
|
|
||||||
// Add a bunch of empty subrs to deal with the Type2 bias
|
|
||||||
for (var i = 0; i < bias; i++)
|
|
||||||
flattenedSubrs.push([0x0B]);
|
|
||||||
|
|
||||||
for (var i = 0; i < subrsCount; i++) {
|
|
||||||
var subr = subrs[i];
|
|
||||||
flattenedSubrs.push(this.flattenCharstring(subr));
|
|
||||||
}
|
|
||||||
|
|
||||||
var subrsData = this.createCFFIndexHeader(flattenedSubrs, true);
|
|
||||||
cff.set(subrsData, currentOffset);
|
cff.set(subrsData, currentOffset);
|
||||||
currentOffset += subrsData.length;
|
currentOffset += subrsData.length;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user