Merge pull request #219 from sbarman/font
Font code cleanup, avoid name collisions
This commit is contained in:
commit
d3979e4ac2
92
fonts.js
92
fonts.js
@ -23,17 +23,20 @@ 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) {
|
var fontCount = 0;
|
||||||
|
|
||||||
|
function FontInfo(name, data, properties) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
|
this.id = fontCount++;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.charsCache = Object.create(null);
|
this.charsCache = Object.create(null);
|
||||||
this.sizes = [];
|
this.sizes = [];
|
||||||
@ -45,24 +48,31 @@ var Fonts = (function Fonts() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
registerFont: function fonts_registerFont(fontName, data, properties) {
|
registerFont: function fonts_registerFont(fontName, data, properties) {
|
||||||
fonts[fontName] = new Font(fontName, data, properties);
|
var font = new FontInfo(fontName, data, properties);
|
||||||
|
fonts.push(font);
|
||||||
|
return font.id;
|
||||||
},
|
},
|
||||||
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(fontName, fontObj, 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 (fontObj && (current = fonts[fontObj.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);
|
||||||
|
} else {
|
||||||
|
charsCache = null;
|
||||||
|
measureCache = null
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"';
|
ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"';
|
||||||
},
|
},
|
||||||
charsToUnicode: function fonts_chars2Unicode(chars) {
|
charsToUnicode: function fonts_chars2Unicode(chars) {
|
||||||
@ -116,9 +126,9 @@ 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 < allIds.length; i++) {
|
||||||
var font = fonts[i];
|
var id = allIds[i];
|
||||||
if (Fonts.lookup(font.name).loading) {
|
if (Fonts.lookupById(id).loading) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,30 +140,35 @@ var FontLoader = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rules = [], names = [];
|
var allIds = [];
|
||||||
|
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;
|
allIds.push(obj.id);
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.listeningForFontLoad = false;
|
||||||
if (!isWorker && rules.length) {
|
if (!isWorker && rules.length) {
|
||||||
FontLoader.prepareFontLoadEvent(rules, names);
|
FontLoader.prepareFontLoadEvent(rules, names, ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkFontsLoaded()) {
|
if (!checkFontsLoaded()) {
|
||||||
document.documentElement.addEventListener(
|
document.documentElement.addEventListener(
|
||||||
'pdfjsFontLoad', checkFontsLoaded, false);
|
'pdfjsFontLoad', checkFontsLoaded, false);
|
||||||
@ -166,7 +181,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
|
||||||
@ -202,13 +217,13 @@ var FontLoader = {
|
|||||||
div.innerHTML = html;
|
div.innerHTML = html;
|
||||||
document.body.appendChild(div);
|
document.body.appendChild(div);
|
||||||
|
|
||||||
if (!this.listeneningForFontLoad) {
|
if (!this.listeningForFontLoad) {
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
'message',
|
'message',
|
||||||
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');
|
||||||
@ -216,7 +231,7 @@ var FontLoader = {
|
|||||||
document.documentElement.dispatchEvent(evt);
|
document.documentElement.dispatchEvent(evt);
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
this.listeneningForFontLoad = true;
|
this.listeningForFontLoad = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX we should have a time-out here too, and maybe fire
|
// XXX we should have a time-out here too, and maybe fire
|
||||||
@ -400,16 +415,11 @@ var Font = (function() {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.encoding = properties.encoding;
|
this.encoding = properties.encoding;
|
||||||
|
|
||||||
// If the font has already been decoded simply return it
|
|
||||||
if (Fonts.lookup(name)) {
|
|
||||||
this.font = Fonts.lookup(name).data;
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +446,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) {
|
||||||
@ -1116,14 +1128,14 @@ var Font = (function() {
|
|||||||
action: 'font',
|
action: 'font',
|
||||||
data: {
|
data: {
|
||||||
raw: data,
|
raw: data,
|
||||||
fontName: this.name,
|
fontName: this.loadedName,
|
||||||
mimetype: this.mimetype
|
mimetype: this.mimetype
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
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,' +
|
||||||
|
29
pdf.js
29
pdf.js
@ -3610,9 +3610,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) {
|
||||||
@ -3873,25 +3874,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(fontName, fontObj, size);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setTextRenderingMode: function(mode) {
|
setTextRenderingMode: function(mode) {
|
||||||
@ -3936,10 +3935,12 @@ 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 = this.current.font;
|
||||||
if (font && font.properties.textMatrix)
|
if (font) {
|
||||||
this.ctx.transform.apply(this.ctx, font.properties.textMatrix);
|
var fontInfo = Fonts.lookupById(font.id);
|
||||||
|
if (fontInfo && fontInfo.properties.textMatrix)
|
||||||
|
this.ctx.transform.apply(this.ctx, fontInfo.properties.textMatrix);
|
||||||
|
}
|
||||||
this.ctx.fillText(text, 0, 0);
|
this.ctx.fillText(text, 0, 0);
|
||||||
this.current.x += Fonts.measureText(text);
|
this.current.x += Fonts.measureText(text);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user