diff --git a/js/data/symbol_bucket.js b/js/data/symbol_bucket.js index 37d548d1a6f..d914a17273b 100644 --- a/js/data/symbol_bucket.js +++ b/js/data/symbol_bucket.js @@ -302,7 +302,6 @@ SymbolBucket.prototype.anchorIsTooClose = function(text, repeatDistance, anchor) }; SymbolBucket.prototype.placeFeatures = function(collisionTile, buffers, collisionDebug) { - // Calculate which labels can be shown and when they can be shown and // create the bufers used for rendering. @@ -319,6 +318,7 @@ SymbolBucket.prototype.placeFeatures = function(collisionTile, buffers, collisio var maxScale = collisionTile.maxScale; elementGroups.glyph['text-size'] = layout['text-size']; + elementGroups.glyph['text-font'] = layout['text-font']; elementGroups.icon['icon-size'] = layout['icon-size']; var textAlongLine = layout['text-rotation-alignment'] === 'map' && layout['symbol-placement'] === 'line'; diff --git a/js/render/draw_symbol.js b/js/render/draw_symbol.js index ee4baaac935..47630dc8565 100644 --- a/js/render/draw_symbol.js +++ b/js/render/draw_symbol.js @@ -119,10 +119,15 @@ function drawSymbol(painter, layer, posMatrix, tile, elementGroups, prefix, sdf, } if (text) { - painter.glyphAtlas.updateTexture(gl); + var textfont = elementGroups['text-font']; + var fontstack = textfont && textfont.join(','); + var glyphAtlas = fontstack && painter.glyphSource.getGlyphAtlas(fontstack); + if (!glyphAtlas) return; + + glyphAtlas.updateTexture(gl); vertex = tile.buffers.glyphVertex; elements = tile.buffers.glyphElement; - texsize = [painter.glyphAtlas.width / 4, painter.glyphAtlas.height / 4]; + texsize = [glyphAtlas.width / 4, glyphAtlas.height / 4]; } else { var mapMoving = painter.options.rotating || painter.options.zooming; var iconScaled = fontScale !== 1 || browser.devicePixelRatio !== painter.spriteAtlas.pixelRatio || iconsNeedLinear; diff --git a/js/render/line_atlas.js b/js/render/line_atlas.js index bbdc4e382ad..9deb748a525 100644 --- a/js/render/line_atlas.js +++ b/js/render/line_atlas.js @@ -3,7 +3,7 @@ module.exports = LineAtlas; /** - * Much like a GlyphAtlas, a LineAtlas lets us reuse rendered dashed lines + * A LineAtlas lets us reuse rendered dashed lines * by writing many of them to a texture and then fetching their positions * using .getDash. * diff --git a/js/render/painter.js b/js/render/painter.js index 02176f7b915..d0626ebb95b 100644 --- a/js/render/painter.js +++ b/js/render/painter.js @@ -269,8 +269,7 @@ Painter.prototype.render = function(style, options) { this.spriteAtlas = style.spriteAtlas; this.spriteAtlas.setSprite(style.sprite); - this.glyphAtlas = style.glyphAtlas; - this.glyphAtlas.bind(this.gl); + this.glyphSource = style.glyphSource; this.frameHistory.record(this.transform.zoom); diff --git a/js/source/geojson_source.js b/js/source/geojson_source.js index 7c7613e0697..43d013fd572 100644 --- a/js/source/geojson_source.js +++ b/js/source/geojson_source.js @@ -190,7 +190,7 @@ GeoJSONSource.prototype = util.inherit(Evented, /** @lends GeoJSONSource.prototy _unloadTile: function(tile) { tile.unloadVectorData(this.map.painter); - this.glyphAtlas.removeGlyphs(tile.uid); + // this.glyphAtlas.removeGlyphs(tile.uid); this.dispatcher.send('remove tile', { uid: tile.uid, source: this.id }, null, tile.workerID); }, diff --git a/js/source/vector_tile_source.js b/js/source/vector_tile_source.js index 82cbb7dea70..7da7dc9ea5a 100644 --- a/js/source/vector_tile_source.js +++ b/js/source/vector_tile_source.js @@ -108,7 +108,7 @@ VectorTileSource.prototype = util.inherit(Evented, { _unloadTile: function(tile) { tile.unloadVectorData(this.map.painter); - this.glyphAtlas.removeGlyphs(tile.uid); + // this.glyphAtlas.removeGlyphs(tile.uid); this.dispatcher.send('remove tile', { uid: tile.uid, source: this.id }, null, tile.workerID); }, diff --git a/js/style/style.js b/js/style/style.js index 72abb2dac23..db7a1a0f6a0 100644 --- a/js/style/style.js +++ b/js/style/style.js @@ -5,7 +5,6 @@ var styleBatch = require('./style_batch'); var StyleLayer = require('./style_layer'); var ImageSprite = require('./image_sprite'); var GlyphSource = require('../symbol/glyph_source'); -var GlyphAtlas = require('../symbol/glyph_atlas'); var SpriteAtlas = require('../symbol/sprite_atlas'); var LineAtlas = require('../render/line_atlas'); var util = require('../util/util'); @@ -21,7 +20,6 @@ module.exports = Style; function Style(stylesheet, animationLoop) { this.animationLoop = animationLoop || new AnimationLoop(); this.dispatcher = new Dispatcher(Math.max(browser.hardwareConcurrency - 1, 1), this); - this.glyphAtlas = new GlyphAtlas(1024, 1024); this.spriteAtlas = new SpriteAtlas(512, 512); this.lineAtlas = new LineAtlas(256, 512); @@ -65,7 +63,7 @@ function Style(stylesheet, animationLoop) { this.sprite.on('load', this.fire.bind(this, 'change')); } - this.glyphSource = new GlyphSource(stylesheet.glyphs, this.glyphAtlas); + this.glyphSource = new GlyphSource(stylesheet.glyphs); this._resolve(); this.fire('load'); }.bind(this); diff --git a/js/style/style_batch.js b/js/style/style_batch.js index 1d7be1bb82f..84ea2d1d3cc 100644 --- a/js/style/style_batch.js +++ b/js/style/style_batch.js @@ -151,7 +151,7 @@ styleBatch.prototype = { source.id = id; source.style = this._style; source.dispatcher = this._style.dispatcher; - source.glyphAtlas = this._style.glyphAtlas; + // source.glyphAtlas = this._style.glyphAtlas; source .on('load', this._style._forwardSourceEvent) .on('error', this._style._forwardSourceEvent) diff --git a/js/symbol/glyph_source.js b/js/symbol/glyph_source.js index 3548fd914c0..ac480188402 100644 --- a/js/symbol/glyph_source.js +++ b/js/symbol/glyph_source.js @@ -3,33 +3,37 @@ var normalizeURL = require('../util/mapbox').normalizeGlyphsURL; var getArrayBuffer = require('../util/ajax').getArrayBuffer; var Glyphs = require('../util/glyphs'); +var GlyphAtlas = require('../symbol/glyph_atlas'); var Protobuf = require('pbf'); module.exports = GlyphSource; /** - * A glyph source has a URL from which to load new glyphs and owns a GlyphAtlas - * that stores currently-loaded glyphs. + * A glyph source has a URL from which to load new glyphs and manages + * GlyphAtlases in which to store glyphs used by the requested fontstacks + * and ranges. * * @param {string} url glyph template url - * @param {Object} glyphAtlas glyph atlas object * @private */ -function GlyphSource(url, glyphAtlas) { +function GlyphSource(url) { this.url = url && normalizeURL(url); - this.glyphAtlas = glyphAtlas; - this.stacks = []; + this.atlases = {}; + this.stacks = {}; this.loading = {}; } GlyphSource.prototype.getSimpleGlyphs = function(fontstack, glyphIDs, uid, callback) { - - if (this.stacks[fontstack] === undefined) this.stacks[fontstack] = {}; + if (this.stacks[fontstack] === undefined) { + this.stacks[fontstack] = {}; + } + if (this.atlases[fontstack] === undefined) { + this.atlases[fontstack] = new GlyphAtlas(2048, 2048); + } var glyphs = {}; - var stack = this.stacks[fontstack]; - var glyphAtlas = this.glyphAtlas; + var atlas = this.atlases[fontstack]; // the number of pixels the sdf bitmaps are padded by var buffer = 3; @@ -44,7 +48,7 @@ GlyphSource.prototype.getSimpleGlyphs = function(fontstack, glyphIDs, uid, callb if (stack[range]) { var glyph = stack[range].glyphs[glyphID]; - var rect = glyphAtlas.addGlyph(uid, fontstack, glyph, buffer); + var rect = atlas.addGlyph(uid, fontstack, glyph, buffer); if (glyph) glyphs[glyphID] = new SimpleGlyph(glyph, rect, buffer); } else { if (missing[range] === undefined) { @@ -64,7 +68,7 @@ GlyphSource.prototype.getSimpleGlyphs = function(fontstack, glyphIDs, uid, callb for (var i = 0; i < missing[range].length; i++) { var glyphID = missing[range][i]; var glyph = stack.glyphs[glyphID]; - var rect = glyphAtlas.addGlyph(uid, fontstack, glyph, buffer); + var rect = atlas.addGlyph(uid, fontstack, glyph, buffer); if (glyph) glyphs[glyphID] = new SimpleGlyph(glyph, rect, buffer); } } @@ -87,10 +91,11 @@ function SimpleGlyph(glyph, rect, buffer) { } GlyphSource.prototype.loadRange = function(fontstack, range, callback) { - if (range * 256 > 65535) return callback('glyphs > 65535 not supported'); - if (this.loading[fontstack] === undefined) this.loading[fontstack] = {}; + if (this.loading[fontstack] === undefined) { + this.loading[fontstack] = {}; + } var loading = this.loading[fontstack]; if (loading[range]) { @@ -111,6 +116,10 @@ GlyphSource.prototype.loadRange = function(fontstack, range, callback) { } }; +GlyphSource.prototype.getGlyphAtlas = function(fontstack) { + return this.atlases[fontstack]; +}; + /** * Use CNAME sharding to load a specific glyph range over a randomized * but consistent subdomain. diff --git a/test/js/source/geojson_source.test.js b/test/js/source/geojson_source.test.js index 81eaeb9122d..e5f33a9e525 100644 --- a/test/js/source/geojson_source.test.js +++ b/test/js/source/geojson_source.test.js @@ -163,9 +163,9 @@ test('GeoJSONSource#update', function(t) { source.map.transform.resize(512, 512); source.style = {}; - source.glyphAtlas = { - removeGlyphs: function() {} - }; + // source.glyphAtlas = { + // removeGlyphs: function() {} + // }; source.update(transform);