Skip to content

Commit 5cbc687

Browse files
committed
Open the CFF class road for Type1C font
1 parent 2e7df01 commit 5cbc687

File tree

1 file changed

+59
-75
lines changed

1 file changed

+59
-75
lines changed

fonts.js

Lines changed: 59 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/**
77
* Maximum file size of the font.
88
*/
9-
var kMaxFontFileSize = 40000;
9+
var kMaxFontFileSize = 200000;
1010

1111
/**
1212
* Maximum time to wait for a font to be loaded by @font-face
@@ -34,7 +34,7 @@ var kDisableFonts = false;
3434
* http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65
3535
*/
3636

37-
var Fonts = (function () {
37+
var Fonts = (function Fonts() {
3838
var kScalePrecision = 40;
3939
var fonts = Object.create(null);
4040
var ctx = document.createElement("canvas").getContext("2d");
@@ -1462,13 +1462,17 @@ var CFF = function(name, file, properties) {
14621462
var length1 = file.dict.get("Length1");
14631463
var length2 = file.dict.get("Length2");
14641464
file.skip(length1);
1465-
var eexecBlock = file.getBytes(length2);
14661465

14671466
// Decrypt the data blocks and retrieve it's content
1467+
var eexecBlock = file.getBytes(length2);
14681468
var data = type1Parser.extractFontProgram(eexecBlock);
14691469

1470-
this.charstrings = this.getOrderedCharStrings(data.charstrings);
1471-
this.data = this.wrap(name, this.charstrings, data.subrs, properties);
1470+
var charstrings = this.getOrderedCharStrings(data.charstrings);
1471+
var type2Charstrings = this.getType2Charstrings(charstrings);
1472+
var subrs = this.getType2Subrs(data.subrs);
1473+
1474+
this.charstrings = charstrings;
1475+
this.data = this.wrap(name, type2Charstrings, this.charstrings, subrs, properties);
14721476
};
14731477

14741478
CFF.prototype = {
@@ -1546,12 +1550,40 @@ CFF.prototype = {
15461550
return charstrings;
15471551
},
15481552

1553+
getType2Charstrings: function cff_getType2Charstrings(type1Charstrings) {
1554+
var type2Charstrings = [];
1555+
var count = type1Charstrings.length;
1556+
for (var i = 0; i < count; i++) {
1557+
var charstring = type1Charstrings[i].charstring;
1558+
type2Charstrings.push(this.flattenCharstring(charstring.slice(), this.commandsMap));
1559+
}
1560+
return type2Charstrings;
1561+
},
1562+
1563+
getType2Subrs: function cff_getType2Charstrings(type1Subrs) {
1564+
var bias = 0;
1565+
var count = type1Subrs.length;
1566+
if (count < 1240)
1567+
bias = 107;
1568+
else if (count < 33900)
1569+
bias = 1131;
1570+
else
1571+
bias = 32768;
1572+
1573+
// Add a bunch of empty subrs to deal with the Type2 bias
1574+
var type2Subrs = [];
1575+
for (var i = 0; i < bias; i++)
1576+
type2Subrs.push([0x0B]);
1577+
1578+
for (var i = 0; i < count; i++)
1579+
type2Subrs.push(this.flattenCharstring(type1Subrs[i], this.commandsMap));
1580+
1581+
return type2Subrs;
1582+
},
1583+
15491584
/*
15501585
* Flatten the commands by interpreting the postscript code and replacing
15511586
* every 'callsubr', 'callothersubr' by the real commands.
1552-
*
1553-
* TODO This function also do a string to command number transformation
1554-
* that can probably be avoided if the Type1 decodeCharstring code is smarter
15551587
*/
15561588
commandsMap: {
15571589
"hstem": 1,
@@ -1573,58 +1605,27 @@ CFF.prototype = {
15731605
"hvcurveto": 31,
15741606
},
15751607

1576-
flattenCharstring: function flattenCharstring(charstring) {
1577-
var i = 0;
1578-
while (true) {
1579-
var obj = charstring[i];
1580-
if (obj == undefined) {
1581-
error("unknow charstring command for " + i + " in " + charstring);
1582-
}
1583-
if (obj.charAt) {
1584-
switch (obj) {
1585-
case "endchar":
1586-
case "return":
1587-
// CharString is ready to be re-encode to commands number at this point
1588-
for (var j = 0; j < charstring.length; j++) {
1589-
var command = charstring[j];
1590-
if (parseFloat(command) == command) {
1591-
charstring.splice(j, 1, 28, command >> 8, command);
1592-
j+= 2;
1593-
} else if (command.charAt) {
1594-
var cmd = this.commandsMap[command];
1595-
if (!cmd)
1596-
error("Unknow command: " + command);
1597-
1598-
if (IsArray(cmd)) {
1599-
charstring.splice(j, 1, cmd[0], cmd[1]);
1600-
j += 1;
1601-
} else {
1602-
charstring[j] = cmd;
1603-
}
1604-
}
1605-
}
1606-
return charstring;
1608+
flattenCharstring: function flattenCharstring(charstring, map) {
1609+
for (var i = 0; i < charstring.length; i++) {
1610+
var command = charstring[i];
1611+
if (command.charAt) {
1612+
var cmd = map[command];
1613+
assert(cmd, "Unknow command: " + command);
16071614

1608-
default:
1609-
break;
1615+
if (IsArray(cmd)) {
1616+
charstring.splice(i++, 1, cmd[0], cmd[1]);
1617+
} else {
1618+
charstring[i] = cmd;
16101619
}
1620+
} else {
1621+
charstring.splice(i, 1, 28, command >> 8, command & 0xff);
1622+
i+= 2;
16111623
}
1612-
i++;
16131624
}
1614-
error("failing with i = " + i + " in charstring:" + charstring + "(" + charstring.length + ")");
1615-
return [];
1625+
return charstring;
16161626
},
16171627

1618-
wrap: function wrap(name, charstrings, subrs, properties) {
1619-
// Starts the conversion of the Type1 charstrings to Type2
1620-
var glyphs = [];
1621-
var glyphsCount = charstrings.length;
1622-
for (var i = 0; i < glyphsCount; i++) {
1623-
var charstring = charstrings[i].charstring;
1624-
glyphs.push(this.flattenCharstring(charstring.slice()));
1625-
}
1626-
1627-
// Create a CFF font data
1628+
wrap: function wrap(name, glyphs, charstrings, subrs, properties) {
16281629
var cff = new Uint8Array(kMaxFontFileSize);
16291630
var currentOffset = 0;
16301631

@@ -1656,10 +1657,12 @@ CFF.prototype = {
16561657

16571658
// Fill the charset header (first byte is the encoding)
16581659
var charset = [0x00];
1660+
var glyphsCount = glyphs.length;
16591661
for (var i = 0; i < glyphsCount; i++) {
16601662
var index = CFFStrings.indexOf(charstrings[i].glyph);
16611663
if (index == -1)
16621664
index = CFFStrings.length + strings.indexOf(charstrings[i].glyph);
1665+
16631666
var bytes = FontsUtils.integerToBytes(index, 2);
16641667
charset.push(bytes[0]);
16651668
charset.push(bytes[1]);
@@ -1731,28 +1734,9 @@ CFF.prototype = {
17311734
cff.set(privateData, currentOffset);
17321735
currentOffset += privateData.length;
17331736

1734-
// Local Subrs
1735-
var flattenedSubrs = [];
1736-
1737-
var bias = 0;
1738-
var subrsCount = subrs.length;
1739-
if (subrsCount < 1240)
1740-
bias = 107;
1741-
else if (subrsCount < 33900)
1742-
bias = 1131;
1743-
else
1744-
bias = 32768;
1745-
1746-
// Add a bunch of empty subrs to deal with the Type2 bias
1747-
for (var i = 0; i < bias; i++)
1748-
flattenedSubrs.push([0x0B]);
1749-
1750-
for (var i = 0; i < subrsCount; i++) {
1751-
var subr = subrs[i];
1752-
flattenedSubrs.push(this.flattenCharstring(subr));
1753-
}
17541737

1755-
var subrsData = this.createCFFIndexHeader(flattenedSubrs, true);
1738+
// Local subrs
1739+
var subrsData = this.createCFFIndexHeader(subrs, true);
17561740
cff.set(subrsData, currentOffset);
17571741
currentOffset += subrsData.length;
17581742

0 commit comments

Comments
 (0)