not refer fonts by name, instead use id

This commit is contained in:
sbarman 2011-07-07 16:48:04 -07:00
parent 65f1058736
commit 8ac2367fa0
2 changed files with 54 additions and 45 deletions

@ -24,17 +24,18 @@ var kMaxWaitForFontFace = 1000;
var Fonts = (function Fonts() { var Fonts = (function Fonts() {
var kScalePrecision = 40; var kScalePrecision = 40;
var fonts = Object.create(null); var fonts = [];
if (!isWorker) { if (!isWorker) {
var ctx = document.createElement('canvas').getContext('2d'); var ctx = document.createElement('canvas').getContext('2d');
ctx.scale(1 / kScalePrecision, 1); ctx.scale(1 / kScalePrecision, 1);
} }
function Font(name, data, properties) { function FontInfo(name, data, properties, id) {
this.name = name; this.name = name;
this.data = data; this.data = data;
this.properties = properties; this.properties = properties;
this.id = id;
this.loading = true; this.loading = true;
this.charsCache = Object.create(null); this.charsCache = Object.create(null);
this.sizes = []; this.sizes = [];
@ -44,27 +45,31 @@ var Fonts = (function Fonts() {
var charsCache; var charsCache;
var measureCache; var measureCache;
var fontCount = 0;
return { return {
registerFont: function fonts_registerFont(fontName, data, properties) { registerFont: function fonts_registerFont(fontName, data, properties) {
fonts[fontName] = new Font(fontName, data, properties); fonts.push(new FontInfo(fontName, data, properties, fontCount));
return fontCount++;
}, },
blacklistFont: function fonts_blacklistFont(fontName) { blacklistFont: function fonts_blacklistFont(fontName) {
registerFont(fontName, null, {}); var id = registerFont(fontName, null, {});
markLoaded(fontName); markLoaded(fontName);
return id;
}, },
lookup: function fonts_lookup(fontName) { lookupById: function fonts_lookupById(id) {
return fonts[fontName]; return fonts[id];
}, },
setActive: function fonts_setActive(fontName, size) { setActive: function fonts_setActive(font, size) {
// |current| can be null is fontName is a built-in font // |current| can be null is fontName is a built-in font
// (e.g. "sans-serif") // (e.g. "sans-serif")
if ((current = fonts[fontName])) { if ((current = fonts[font.id])) {
charsCache = current.charsCache; charsCache = current.charsCache;
var sizes = current.sizes; var sizes = current.sizes;
if (!(measureCache = sizes[size])) if (!(measureCache = sizes[size]))
measureCache = sizes[size] = Object.create(null); measureCache = sizes[size] = Object.create(null);
} }
ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"'; ctx.font = (size * kScalePrecision) + 'px "' + font.loadedName + '"';
}, },
charsToUnicode: function fonts_chars2Unicode(chars) { charsToUnicode: function fonts_chars2Unicode(chars) {
if (!charsCache) if (!charsCache)
@ -118,8 +123,8 @@ var FontLoader = {
bind: function(fonts, callback) { bind: function(fonts, callback) {
function checkFontsLoaded() { function checkFontsLoaded() {
for (var i = 0; i < fonts.length; i++) { for (var i = 0; i < fonts.length; i++) {
var font = fonts[i]; var id = fonts[i].fontDict.fontObj.id;
if (Fonts.lookup(font.name).loading) { if (Fonts.lookupById(id).loading) {
return false; return false;
} }
} }
@ -131,28 +136,29 @@ var FontLoader = {
return true; return true;
} }
var rules = [], names = []; var rules = [], names = [], ids = [];
for (var i = 0; i < fonts.length; i++) { for (var i = 0; i < fonts.length; i++) {
var font = fonts[i]; var font = fonts[i];
if (!Fonts.lookup(font.name)) {
var obj = new Font(font.name, font.file, font.properties);
var str = ''; var obj = new Font(font.name, font.file, font.properties);
var data = Fonts.lookup(font.name).data; font.fontDict.fontObj = obj;
var length = data.length;
for (var j = 0; j < length; j++)
str += String.fromCharCode(data[j]);
var rule = isWorker ? obj.bindWorker(str) : obj.bindDOM(str); var str = '';
if (rule) { var data = Fonts.lookupById(obj.id).data;
rules.push(rule); var length = data.length;
names.push(font.name); for (var j = 0; j < length; j++)
} str += String.fromCharCode(data[j]);
var rule = isWorker ? obj.bindWorker(str) : obj.bindDOM(str);
if (rule) {
rules.push(rule);
names.push(obj.loadedName);
ids.push(obj.id);
} }
} }
if (!isWorker && rules.length) { if (!isWorker && rules.length) {
FontLoader.prepareFontLoadEvent(rules, names); FontLoader.prepareFontLoadEvent(rules, names, ids);
} }
if (!checkFontsLoaded()) { if (!checkFontsLoaded()) {
@ -167,7 +173,7 @@ var FontLoader = {
// loaded in a subdocument. It's expected that the load of |rules| // loaded in a subdocument. It's expected that the load of |rules|
// has already started in this (outer) document, so that they should // has already started in this (outer) document, so that they should
// be ordered before the load in the subdocument. // be ordered before the load in the subdocument.
prepareFontLoadEvent: function(rules, names) { prepareFontLoadEvent: function(rules, names, ids) {
/** Hack begin */ /** Hack begin */
// There's no event when a font has finished downloading so the // There's no event when a font has finished downloading so the
// following code is a dirty hack to 'guess' when a font is // following code is a dirty hack to 'guess' when a font is
@ -209,7 +215,7 @@ var FontLoader = {
function(e) { function(e) {
var fontNames = JSON.parse(e.data); var fontNames = JSON.parse(e.data);
for (var i = 0; i < fontNames.length; ++i) { for (var i = 0; i < fontNames.length; ++i) {
var font = Fonts.lookup(fontNames[i]); var font = Fonts.lookupById(ids[i]);
font.loading = false; font.loading = false;
} }
var evt = document.createEvent('Events'); var evt = document.createEvent('Events');
@ -402,15 +408,16 @@ var Font = (function() {
this.encoding = properties.encoding; this.encoding = properties.encoding;
// If the font has already been decoded simply return it // If the font has already been decoded simply return it
if (Fonts.lookup(name)) { //if (Fonts.lookup(name)) {
this.font = Fonts.lookup(name).data; // this.font = Fonts.lookup(name).data;
return; // return;
} //}
// If the font is to be ignored, register it like an already loaded font // If the font is to be ignored, register it like an already loaded font
// to avoid the cost of waiting for it be be loaded by the platform. // to avoid the cost of waiting for it be be loaded by the platform.
if (properties.ignore) { if (properties.ignore) {
Fonts.blacklistFont(name); this.id = Fonts.blacklistFont(name);
this.loadedName = 'pdfFont' + this.id;
return; return;
} }
@ -437,7 +444,9 @@ var Font = (function() {
break; break;
} }
this.data = data; this.data = data;
Fonts.registerFont(name, data, properties);
this.id = Fonts.registerFont(name, data, properties);
this.loadedName = 'pdfFont' + this.id;
}; };
function stringToArray(str) { function stringToArray(str) {
@ -1124,7 +1133,7 @@ var Font = (function() {
}, },
bindDOM: function font_bindDom(data) { bindDOM: function font_bindDom(data) {
var fontName = this.name; var fontName = this.loadedName;
// Add the font-face rule to the document // Add the font-face rule to the document
var url = ('url(data:' + this.mimetype + ';base64,' + var url = ('url(data:' + this.mimetype + ';base64,' +

22
pdf.js

@ -3605,9 +3605,10 @@ var CanvasGraphics = (function() {
return { return {
name: fontName, name: fontName,
file: fontFile, fontDict: fontDict,
properties: properties file: fontFile,
}; properties: properties
};
}, },
beginDrawing: function(mediaBox) { beginDrawing: function(mediaBox) {
@ -3686,6 +3687,7 @@ var CanvasGraphics = (function() {
var font = xref.fetchIfRef(fontRes.get(args[0].name)); var font = xref.fetchIfRef(fontRes.get(args[0].name));
assertWellFormed(IsDict(font)); assertWellFormed(IsDict(font));
if (!font.translated) { if (!font.translated) {
// sbarman marker
font.translated = this.translateFont(font, xref, resources); font.translated = this.translateFont(font, xref, resources);
if (fonts && font.translated) { if (fonts && font.translated) {
// keep track of each font we translated so the caller can // keep track of each font we translated so the caller can
@ -3868,25 +3870,23 @@ var CanvasGraphics = (function() {
return; return;
var fontName = ''; var fontName = '';
var fontDescriptor = font.get('FontDescriptor'); var fontObj = font.fontObj;
if (fontDescriptor && fontDescriptor.num) { if (fontObj)
var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); fontName = fontObj.loadedName;
fontName = fontDescriptor.get('FontName').name.replace('+', '_');
}
if (!fontName) { if (!fontName) {
// TODO: fontDescriptor is not available, fallback to default font // TODO: fontDescriptor is not available, fallback to default font
fontName = 'sans-serif'; fontName = 'sans-serif';
} }
this.current.fontName = fontName; this.current.font = fontObj;
this.current.fontSize = size; this.current.fontSize = size;
if (this.ctx.$setFont) { if (this.ctx.$setFont) {
this.ctx.$setFont(fontName, size); this.ctx.$setFont(fontName, size);
} else { } else {
this.ctx.font = size + 'px "' + fontName + '"'; this.ctx.font = size + 'px "' + fontName + '"';
Fonts.setActive(fontName, size); Fonts.setActive(font, size);
} }
}, },
setTextRenderingMode: function(mode) { setTextRenderingMode: function(mode) {
@ -3931,7 +3931,7 @@ var CanvasGraphics = (function() {
text = Fonts.charsToUnicode(text); text = Fonts.charsToUnicode(text);
this.ctx.translate(this.current.x, -1 * this.current.y); this.ctx.translate(this.current.x, -1 * this.current.y);
var font = Fonts.lookup(this.current.fontName); var font = Fonts.lookupById(this.current.font.id);
if (font && font.properties.textMatrix) if (font && font.properties.textMatrix)
this.ctx.transform.apply(this.ctx, font.properties.textMatrix); this.ctx.transform.apply(this.ctx, font.properties.textMatrix);