Skip to content

Commit be6397f

Browse files
committed
Merge pull request mozilla#139 from andreasgal/staging
cache font measurements
2 parents 98f47ba + 05381cc commit be6397f

File tree

1 file changed

+83
-70
lines changed

1 file changed

+83
-70
lines changed

fonts.js

Lines changed: 83 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -34,65 +34,89 @@ var kDisableFonts = false;
3434
* http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65
3535
*/
3636

37-
var kScalePrecision = 40;
38-
var Fonts = {
39-
_active: null,
37+
var Fonts = (function () {
38+
var kScalePrecision = 40;
39+
var fonts = Object.create(null);
40+
var ctx = document.createElement("canvas").getContext("2d");
41+
ctx.scale(1 / kScalePrecision, 1);
4042

41-
get active() {
42-
return this._active;
43-
},
44-
45-
setActive: function fonts_setActive(name, size) {
46-
this._active = this[name];
47-
this.ctx.font = (size * kScalePrecision) + 'px "' + name + '"';
48-
},
49-
50-
charsToUnicode: function fonts_chars2Unicode(chars) {
51-
var active = this._active;
52-
if (!active)
53-
return chars;
54-
55-
// if we translated this string before, just grab it from the cache
56-
var str = active.cache[chars];
57-
if (str)
58-
return str;
59-
60-
// translate the string using the font's encoding
61-
var encoding = active.properties.encoding;
62-
if (!encoding)
63-
return chars;
43+
function Font(name, data, properties) {
44+
this.name = name;
45+
this.data = data;
46+
this.properties = properties;
47+
this.loading = true;
48+
this.charsCache = Object.create(null);
49+
this.sizes = [];
50+
}
6451

65-
str = "";
66-
for (var i = 0; i < chars.length; ++i) {
67-
var charcode = chars.charCodeAt(i);
68-
var unicode = encoding[charcode];
52+
var current;
53+
var charsCache;
54+
var measureCache;
6955

70-
// Check if the glyph has already been converted
71-
if (!IsNum(unicode))
56+
return {
57+
registerFont: function fonts_registerFont(fontName, data, properties) {
58+
fonts[fontName] = new Font(fontName, data, properties);
59+
},
60+
blacklistFont: function fonts_blacklistFont(fontName) {
61+
registerFont(fontName, null, {});
62+
markLoaded(fontName);
63+
},
64+
lookup: function fonts_lookup(fontName) {
65+
return fonts[fontName];
66+
},
67+
setActive: function fonts_setActive(fontName, size) {
68+
current = fonts[fontName];
69+
charsCache = current.charsCache;
70+
var sizes = current.sizes;
71+
if (!(measureCache = sizes[size]))
72+
measureCache = sizes[size] = Object.create(null);
73+
ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"';
74+
},
75+
charsToUnicode: function fonts_chars2Unicode(chars) {
76+
if (!charsCache)
77+
return chars;
78+
79+
// if we translated this string before, just grab it from the cache
80+
var str = charsCache[chars];
81+
if (str)
82+
return str;
83+
84+
// translate the string using the font's encoding
85+
var encoding = current.properties.encoding;
86+
if (!encoding)
87+
return chars;
88+
89+
str = "";
90+
for (var i = 0; i < chars.length; ++i) {
91+
var charcode = chars.charCodeAt(i);
92+
var unicode = encoding[charcode];
93+
94+
// Check if the glyph has already been converted
95+
if (!IsNum(unicode))
7296
unicode = encoding[unicode] = GlyphsUnicode[unicode.name];
7397

74-
// Handle surrogate pairs
75-
if (unicode > 0xFFFF) {
76-
str += String.fromCharCode(unicode & 0xFFFF);
77-
unicode >>= 16;
98+
// Handle surrogate pairs
99+
if (unicode > 0xFFFF) {
100+
str += String.fromCharCode(unicode & 0xFFFF);
101+
unicode >>= 16;
102+
}
103+
str += String.fromCharCode(unicode);
78104
}
79-
str += String.fromCharCode(unicode);
80-
}
81-
82-
// Enter the translated string into the cache
83-
return active.cache[chars] = str;
84-
},
85105

86-
get ctx() {
87-
var ctx = document.createElement("canvas").getContext("2d");
88-
ctx.scale(1 / kScalePrecision, 1);
89-
return shadow(this, "ctx", ctx);
90-
},
91-
92-
measureText: function fonts_measureText(text) {
93-
return this.ctx.measureText(text).width / kScalePrecision;
106+
// Enter the translated string into the cache
107+
return charsCache[chars] = str;
108+
},
109+
measureText: function fonts_measureText(text) {
110+
var width;
111+
if (measureCache && (width = measureCache[text]))
112+
return width;
113+
width = ctx.measureText(text).width / kScalePrecision;
114+
if (measureCache)
115+
measureCache[text] = width;
116+
return width;
117+
}
94118
}
95-
};
119+
})();
96120

97121
var FontLoader = {
98122
bind: function(fonts) {
@@ -101,8 +125,8 @@ var FontLoader = {
101125

102126
for (var i = 0; i < fonts.length; i++) {
103127
var font = fonts[i];
104-
if (Fonts[font.name]) {
105-
ready = ready && !Fonts[font.name].loading;
128+
if (Fonts.lookup(font.name)) {
129+
ready = ready && !Fonts.lookup(font.name).loading;
106130
continue;
107131
}
108132

@@ -111,7 +135,7 @@ var FontLoader = {
111135
var obj = new Font(font.name, font.file, font.properties);
112136

113137
var str = "";
114-
var data = Fonts[font.name].data;
138+
var data = Fonts.lookup(font.name).data;
115139
var length = data.length;
116140
for (var j = 0; j < length; j++)
117141
str += String.fromCharCode(data[j]);
@@ -138,8 +162,8 @@ var Font = (function () {
138162
this.encoding = properties.encoding;
139163

140164
// If the font has already been decoded simply return it
141-
if (Fonts[name]) {
142-
this.font = Fonts[name].data;
165+
if (Fonts.lookup(name)) {
166+
this.font = Fonts.lookup(name).data;
143167
return;
144168
}
145169
fontCount++;
@@ -148,12 +172,7 @@ var Font = (function () {
148172
// If the font is to be ignored, register it like an already loaded font
149173
// to avoid the cost of waiting for it be be loaded by the platform.
150174
if (properties.ignore || kDisableFonts) {
151-
Fonts[name] = {
152-
data: file,
153-
loading: false,
154-
properties: {},
155-
cache: Object.create(null)
156-
}
175+
Fonts.blacklistFont(name);
157176
return;
158177
}
159178

@@ -180,13 +199,7 @@ var Font = (function () {
180199
break;
181200
}
182201
this.data = data;
183-
184-
Fonts[name] = {
185-
data: data,
186-
properties: properties,
187-
loading: true,
188-
cache: Object.create(null)
189-
};
202+
Fonts.registerFont(name, data, properties);
190203
};
191204

192205
function stringToArray(str) {
@@ -833,7 +846,7 @@ var Font = (function () {
833846
}
834847

835848
window.clearInterval(interval);
836-
Fonts[fontName].loading = false;
849+
Fonts.lookup(fontName).loading = false;
837850
this.start = 0;
838851
if (callback) {
839852
callback();

0 commit comments

Comments
 (0)