Add Encodings.js and change the code to generate a CharSet per font, this will allow future changes to the OpenType font generator

This commit is contained in:
Vivien Nicolas 2011-06-15 05:40:54 +02:00
parent 1dcd42b66c
commit f7e90f569c
4 changed files with 1584 additions and 34 deletions

1552
Encodings.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ var Fonts = {
unicodeFromCode: function fonts_unicodeFromCode(aCode) { unicodeFromCode: function fonts_unicodeFromCode(aCode) {
var active = this._active; var active = this._active;
if (!active) if (!active || !active.encoding)
return aCode; return aCode;
var difference = active.encoding[aCode]; var difference = active.encoding[aCode];
@ -60,7 +60,7 @@ var Fonts = {
* As an improvment the last parameter can be replaced by an automatic guess * As an improvment the last parameter can be replaced by an automatic guess
* of the font type based on the first byte of the file. * of the font type based on the first byte of the file.
*/ */
var Font = function(aName, aFile, aEncoding, aType) { var Font = function(aName, aFile, aEncoding, aCharset, aType) {
this.name = aName; this.name = aName;
// If the font has already been decoded simply return // If the font has already been decoded simply return
@ -95,6 +95,7 @@ var Font = function(aName, aFile, aEncoding, aType) {
Fonts[aName] = { Fonts[aName] = {
data: this.font, data: this.font,
encoding: aEncoding, encoding: aEncoding,
charset: aCharset ? aCharset.slice() : null,
loading: true loading: true
} }
@ -125,10 +126,10 @@ Font.prototype = {
// Actually there is not event when a font has finished downloading so // Actually there is not event when a font has finished downloading so
// the following tons of code are a dirty hack to 'guess' when a font is // the following tons of code are a dirty hack to 'guess' when a font is
// ready // ready
var debug = false; var debug = true;
var canvas = document.createElement("canvas"); var canvas = document.createElement("canvas");
var style = "position:absolute; top: " + var style = "border: 1px solid black; position:absolute; top: " +
(debug ? (80 * fontCount) : "-200") + "px; left: 100px;"; (debug ? (80 * fontCount) : "-200") + "px; left: 100px;";
canvas.setAttribute("style", style); canvas.setAttribute("style", style);
canvas.setAttribute("width", 100); canvas.setAttribute("width", 100);
@ -136,40 +137,19 @@ Font.prototype = {
document.body.appendChild(canvas); document.body.appendChild(canvas);
// Retrieve font charset // Retrieve font charset
var charset = null; var charset = Fonts[fontName].charset || [];
var page = pdfDocument.getPage(pageNum); // if the charset is too small make it repeat a few times
var xref = page.xref; var count = 30;
while (count-- && charset.length <= 30)
var fonts = page.fonts; charset = charset.concat(charset.slice());
fonts.forEach(function(fontKey, fontData) {
var descriptor = xref.fetch(fontData.get("FontDescriptor"));
var name = descriptor.get("FontName").toString();
var font = Fonts[name.replace("+", "_")];
if (font && font.loading && name == fontName.replace("_", "+")) {
charset = descriptor.get("CharSet");
charset = charset ? charset.split("/") : null;
return;
}
});
// Warn if the charset is not found, this is likely
var testCharset = charset || [];
if (!charset) {
warn("No charset found for: " + fontName);
} else {
// if the charset is too small make it repeat a few times
var count = 30;
while (count-- && testCharset.length <= 30)
testCharset = testCharset.concat(charset.slice());
}
// Get the font size canvas think it will be // Get the font size canvas think it will be
var ctx = canvas.getContext("2d"); var ctx = canvas.getContext("2d");
var testString = ""; var testString = "";
for (var i = 0; i < testCharset.length; i++) { for (var i = 0; i < charset.length; i++) {
var unicode = new Number("0x" + GlyphsUnicode[testCharset[i]]); var unicode = new Number("0x" + GlyphsUnicode[charset[i]]);
if (!unicode) if (!unicode)
error("Unicode for " + testCharset[i] + " is has not been found in the glyphs list"); error("Unicode for " + charset[i] + " is has not been found in the glyphs list");
testString += String.fromCharCode(unicode); testString += String.fromCharCode(unicode);
} }
ctx.font = "20px " + fontName + ", Symbol"; ctx.font = "20px " + fontName + ", Symbol";

View File

@ -7,6 +7,7 @@
<script type="text/javascript" src="test.js"></script> <script type="text/javascript" src="test.js"></script>
<script type="text/javascript" src="cffStandardStrings.js"></script> <script type="text/javascript" src="cffStandardStrings.js"></script>
<script type="text/javascript" src="glyphlist.js"></script> <script type="text/javascript" src="glyphlist.js"></script>
<script type="text/javascript" src="Encodings.js"></script>
<script type="text/javascript" src="PDFFont.js"></script> <script type="text/javascript" src="PDFFont.js"></script>
</head> </head>

19
test.js
View File

@ -93,17 +93,34 @@ function displayPage(num) {
if (fontDict.has("Encoding")) { if (fontDict.has("Encoding")) {
var encoding = xref.fetchIfRef(fontDict.get("Encoding")); var encoding = xref.fetchIfRef(fontDict.get("Encoding"));
if (IsDict(encoding)) { if (IsDict(encoding)) {
// Build an map between codes and glyphs
var differences = encoding.get("Differences"); var differences = encoding.get("Differences");
var index = 0; var index = 0;
for (var j = 0; j < differences.length; j++) { for (var j = 0; j < differences.length; j++) {
var data = differences[j]; var data = differences[j];
IsNum(data) ? index = data : encodingMap[index++] = data; IsNum(data) ? index = data : encodingMap[index++] = data;
} }
// Get the font charset
var charset = descriptor.get("CharSet").split("/");
} else if (IsName(encoding)) {
var encoding = Encodings[encoding];
var widths = xref.fetchIfRef(fontDict.get("Widths"));
var firstchar = xref.fetchIfRef(fontDict.get("FirstChar"));
var charset = [];
for (var j = 0; j < widths.length; j++) {
var index = widths[j];
if (index)
charset.push(encoding[j + firstchar]);
}
} }
} }
var subtype = fontDict.get("Subtype").name; var subtype = fontDict.get("Subtype").name;
new Font(fontName, fontFile, encodingMap, subtype); new Font(fontName, fontFile, encodingMap, charset, subtype);
return fontsReady = false; return fontsReady = false;
} else if (font.loading) { } else if (font.loading) {
return fontsReady = false; return fontsReady = false;