Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions src/components/text.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var createTextGeometry = require('three-bmfont-text');
var loadBMFont = require('load-bmfont');
var path = require('path');

var registerComponent = require('../core/component').registerComponent;
var coreShader = require('../core/shader');
Expand Down Expand Up @@ -35,6 +34,7 @@ module.exports.FONTS = FONTS;

var cache = new PromiseCache();
var fontWidthFactors = {};
var textures = {};

/**
* SDF-based text component.
Expand Down Expand Up @@ -81,11 +81,7 @@ module.exports.Component = registerComponent('text', {
},

init: function () {
this.texture = new THREE.Texture();
this.texture.anisotropy = MAX_ANISOTROPY;

this.geometry = createTextGeometry();

this.createOrUpdateMaterial();
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.el.setObject3D(this.attrName, this.mesh);
Expand All @@ -94,6 +90,15 @@ module.exports.Component = registerComponent('text', {
update: function (oldData) {
var data = coerceData(this.data);
var font = this.currentFont;
var fontImage = this.getFontImageSrc();

if (textures[fontImage]) {
this.texture = textures[fontImage];
} else {
// Create texture per font.
this.texture = textures[fontImage] = new THREE.Texture();
this.texture.anisotropy = MAX_ANISOTROPY;
}

// Update material.
this.createOrUpdateMaterial();
Expand Down Expand Up @@ -216,15 +221,17 @@ module.exports.Component = registerComponent('text', {
self.updateLayout(coercedData);

// Look up font image URL to use, and perform cached load.
fontImgSrc = data.fontImage || fontSrc.replace(/(\.fnt)|(\.json)/, '.png') ||
path.dirname(data.font) + '/' + font.pages[0];
fontImgSrc = self.getFontImageSrc();
cache.get(fontImgSrc, function () {
return loadTexture(fontImgSrc);
}).then(function (image) {
// Make mesh visible and apply font image as texture.
var texture = self.texture;
texture.image = image;
texture.needsUpdate = true;
textures[fontImgSrc] = texture;
self.texture = texture;
self.mesh.visible = true;
self.texture.image = image;
self.texture.needsUpdate = true;
el.emit('textfontset', {font: data.font, fontObj: font});
}).catch(function (err) {
error(err);
Expand All @@ -236,6 +243,11 @@ module.exports.Component = registerComponent('text', {
});
},

getFontImageSrc: function () {
var fontSrc = this.lookupFont(this.data.font || DEFAULT_FONT) || this.data.font;
return this.data.fontImage || fontSrc.replace(/(\.fnt)|(\.json)/, '.png');
},

/**
* Update layout with anchor, alignment, baseline, and considering any meshes.
*/
Expand Down
10 changes: 10 additions & 0 deletions tests/components/text.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ suite('text', function () {
el.setAttribute('text', 'shader', 'sdf');
assert.equal(updateMaterialSpy.getCalls().length, 2);
});

test('caches texture', function (done) {
var el2 = document.createElement('a-entity');
el2.setAttribute('text', '');
el.appendChild(el2);
setTimeout(() => {
assert.equal(el.components.text.texture, el2.components.text.texture);
done();
});
});
});

suite('createOrUpdateMaterial', function () {
Expand Down