Check if fonts are available and redraw when label cache was cleared
This commit is contained in:
@@ -12,6 +12,7 @@ ol.events.EventType = {
|
|||||||
*/
|
*/
|
||||||
CHANGE: 'change',
|
CHANGE: 'change',
|
||||||
|
|
||||||
|
CLEAR: 'clear',
|
||||||
CLICK: 'click',
|
CLICK: 'click',
|
||||||
DBLCLICK: 'dblclick',
|
DBLCLICK: 'dblclick',
|
||||||
DRAGENTER: 'dragenter',
|
DRAGENTER: 'dragenter',
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
goog.provide('ol.render.canvas');
|
goog.provide('ol.render.canvas');
|
||||||
|
|
||||||
|
|
||||||
|
goog.require('ol.css');
|
||||||
|
goog.require('ol.dom');
|
||||||
|
goog.require('ol.structs.LRUCache');
|
||||||
goog.require('ol.transform');
|
goog.require('ol.transform');
|
||||||
|
|
||||||
|
|
||||||
@@ -81,6 +84,73 @@ ol.render.canvas.defaultTextBaseline = 'middle';
|
|||||||
ol.render.canvas.defaultLineWidth = 1;
|
ol.render.canvas.defaultLineWidth = 1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.structs.LRUCache.<HTMLCanvasElement>}
|
||||||
|
*/
|
||||||
|
ol.render.canvas.labelCache = new ol.structs.LRUCache();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {!Object.<string, boolean>}
|
||||||
|
*/
|
||||||
|
ol.render.canvas.checkedFonts_ = {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the label cache when a font becomes available.
|
||||||
|
* @param {string} fontSpec CSS font spec.
|
||||||
|
*/
|
||||||
|
ol.render.canvas.checkFont = (function() {
|
||||||
|
var checked = ol.render.canvas.checkedFonts_;
|
||||||
|
var labelCache = ol.render.canvas.labelCache;
|
||||||
|
var text = 'wmytzilWMYTZIL@#/&?$%10';
|
||||||
|
var context, referenceWidth;
|
||||||
|
|
||||||
|
function isAvailable(fontFamily) {
|
||||||
|
if (!context) {
|
||||||
|
context = ol.dom.createCanvasContext2D();
|
||||||
|
context.font = '32px monospace';
|
||||||
|
referenceWidth = context.measureText(text).width;
|
||||||
|
}
|
||||||
|
var available = true;
|
||||||
|
if (fontFamily != 'monospace') {
|
||||||
|
context.font = '32px ' + fontFamily + ',monospace';
|
||||||
|
var width = context.measureText(text).width;
|
||||||
|
// If width and referenceWidth are the same, then the 'monospace'
|
||||||
|
// fallback was used instead of the font we wanted, so the font is not
|
||||||
|
// available.
|
||||||
|
available = width != referenceWidth;
|
||||||
|
}
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(fontSpec) {
|
||||||
|
var fontFamilies = ol.css.getFontFamilies(fontSpec);
|
||||||
|
if (!fontFamilies) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fontFamilies.forEach(function(fontFamily) {
|
||||||
|
if (!checked[fontFamily]) {
|
||||||
|
checked[fontFamily] = true;
|
||||||
|
if (!isAvailable(fontFamily)) {
|
||||||
|
var callCount = 0;
|
||||||
|
var interval = window.setInterval(function() {
|
||||||
|
++callCount;
|
||||||
|
var available = isAvailable(fontFamily);
|
||||||
|
if (available || callCount >= 60) {
|
||||||
|
window.clearInterval(interval);
|
||||||
|
if (available) {
|
||||||
|
labelCache.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
* @param {CanvasRenderingContext2D} context Context.
|
||||||
* @param {number} rotation Rotation.
|
* @param {number} rotation Rotation.
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ goog.require('ol.render.canvas');
|
|||||||
goog.require('ol.render.canvas.Instruction');
|
goog.require('ol.render.canvas.Instruction');
|
||||||
goog.require('ol.render.canvas.Replay');
|
goog.require('ol.render.canvas.Replay');
|
||||||
goog.require('ol.render.replay');
|
goog.require('ol.render.replay');
|
||||||
goog.require('ol.structs.LRUCache');
|
|
||||||
goog.require('ol.style.TextPlacement');
|
goog.require('ol.style.TextPlacement');
|
||||||
|
|
||||||
|
|
||||||
@@ -121,21 +120,10 @@ ol.render.canvas.TextReplay = function(
|
|||||||
*/
|
*/
|
||||||
this.widths_ = {};
|
this.widths_ = {};
|
||||||
|
|
||||||
while (ol.render.canvas.TextReplay.labelCache_.canExpireCache()) {
|
|
||||||
ol.render.canvas.TextReplay.labelCache_.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
ol.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay);
|
ol.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.structs.LRUCache.<HTMLCanvasElement>}
|
|
||||||
*/
|
|
||||||
ol.render.canvas.TextReplay.labelCache_ = new ol.structs.LRUCache();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} font Font to use for measuring.
|
* @param {string} font Font to use for measuring.
|
||||||
* @return {ol.Size} Measurement.
|
* @return {ol.Size} Measurement.
|
||||||
@@ -324,7 +312,8 @@ ol.render.canvas.TextReplay.prototype.getImage = function(text, fill, stroke) {
|
|||||||
var label;
|
var label;
|
||||||
var key = (stroke ? this.strokeKey_ : '') + this.textKey_ + text + (fill ? this.fillKey_ : '');
|
var key = (stroke ? this.strokeKey_ : '') + this.textKey_ + text + (fill ? this.fillKey_ : '');
|
||||||
|
|
||||||
if (!ol.render.canvas.TextReplay.labelCache_.containsKey(key)) {
|
var labelCache = ol.render.canvas.labelCache;
|
||||||
|
if (!labelCache.containsKey(key)) {
|
||||||
var strokeState = this.textStrokeState_;
|
var strokeState = this.textStrokeState_;
|
||||||
var fillState = this.textFillState_;
|
var fillState = this.textFillState_;
|
||||||
var textState = this.textState_;
|
var textState = this.textState_;
|
||||||
@@ -344,7 +333,7 @@ ol.render.canvas.TextReplay.prototype.getImage = function(text, fill, stroke) {
|
|||||||
Math.ceil(renderWidth * scale),
|
Math.ceil(renderWidth * scale),
|
||||||
Math.ceil((height + strokeWidth) * scale));
|
Math.ceil((height + strokeWidth) * scale));
|
||||||
label = context.canvas;
|
label = context.canvas;
|
||||||
ol.render.canvas.TextReplay.labelCache_.set(key, label);
|
labelCache.pruneAndSet(key, label);
|
||||||
if (scale != 1) {
|
if (scale != 1) {
|
||||||
context.scale(scale, scale);
|
context.scale(scale, scale);
|
||||||
}
|
}
|
||||||
@@ -379,7 +368,7 @@ ol.render.canvas.TextReplay.prototype.getImage = function(text, fill, stroke) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ol.render.canvas.TextReplay.labelCache_.get(key);
|
return labelCache.get(key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -537,6 +526,7 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle, declutt
|
|||||||
if (!textState) {
|
if (!textState) {
|
||||||
textState = this.textState_ = /** @type {ol.CanvasTextState} */ ({});
|
textState = this.textState_ = /** @type {ol.CanvasTextState} */ ({});
|
||||||
}
|
}
|
||||||
|
ol.render.canvas.checkFont(font);
|
||||||
textState.exceedLength = textStyle.getExceedLength();
|
textState.exceedLength = textStyle.getExceedLength();
|
||||||
textState.font = font;
|
textState.font = font;
|
||||||
textState.maxAngle = textStyle.getMaxAngle();
|
textState.maxAngle = textStyle.getMaxAngle();
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ goog.require('ol');
|
|||||||
goog.require('ol.LayerType');
|
goog.require('ol.LayerType');
|
||||||
goog.require('ol.ViewHint');
|
goog.require('ol.ViewHint');
|
||||||
goog.require('ol.dom');
|
goog.require('ol.dom');
|
||||||
|
goog.require('ol.events');
|
||||||
|
goog.require('ol.events.EventType');
|
||||||
goog.require('ol.ext.rbush');
|
goog.require('ol.ext.rbush');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.render.EventType');
|
goog.require('ol.render.EventType');
|
||||||
@@ -73,6 +75,8 @@ ol.renderer.canvas.VectorLayer = function(vectorLayer) {
|
|||||||
*/
|
*/
|
||||||
this.context_ = ol.dom.createCanvasContext2D();
|
this.context_ = ol.dom.createCanvasContext2D();
|
||||||
|
|
||||||
|
ol.events.listen(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
|
||||||
|
|
||||||
};
|
};
|
||||||
ol.inherits(ol.renderer.canvas.VectorLayer, ol.renderer.canvas.Layer);
|
ol.inherits(ol.renderer.canvas.VectorLayer, ol.renderer.canvas.Layer);
|
||||||
|
|
||||||
@@ -99,6 +103,15 @@ ol.renderer.canvas.VectorLayer['create'] = function(mapRenderer, layer) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.VectorLayer.prototype.disposeInternal = function() {
|
||||||
|
ol.events.unlisten(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
|
||||||
|
ol.renderer.canvas.Layer.prototype.disposeInternal.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -259,6 +272,17 @@ ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate = function(c
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.events.Event} event Event.
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.VectorLayer.prototype.handleFontsChanged_ = function(event) {
|
||||||
|
var layer = this.getLayer();
|
||||||
|
if (layer.getVisible() && this.replayGroup_) {
|
||||||
|
layer.changed();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle changes in image style state.
|
* Handle changes in image style state.
|
||||||
* @param {ol.events.Event} event Image style change event.
|
* @param {ol.events.Event} event Image style change event.
|
||||||
@@ -410,7 +434,7 @@ ol.renderer.canvas.VectorLayer.prototype.renderFeature = function(feature, resol
|
|||||||
loading = ol.renderer.vector.renderFeature(
|
loading = ol.renderer.vector.renderFeature(
|
||||||
replayGroup, feature, styles,
|
replayGroup, feature, styles,
|
||||||
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||||
this.handleStyleImageChange_, this) || loading;
|
this.handleStyleImageChange_, this);
|
||||||
}
|
}
|
||||||
return loading;
|
return loading;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ goog.require('ol');
|
|||||||
goog.require('ol.LayerType');
|
goog.require('ol.LayerType');
|
||||||
goog.require('ol.TileState');
|
goog.require('ol.TileState');
|
||||||
goog.require('ol.dom');
|
goog.require('ol.dom');
|
||||||
|
goog.require('ol.events');
|
||||||
|
goog.require('ol.events.EventType');
|
||||||
goog.require('ol.ext.rbush');
|
goog.require('ol.ext.rbush');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.layer.VectorTileRenderType');
|
goog.require('ol.layer.VectorTileRenderType');
|
||||||
@@ -61,6 +63,9 @@ ol.renderer.canvas.VectorTileLayer = function(layer) {
|
|||||||
// Use lower resolution for pure vector rendering. Closest resolution otherwise.
|
// Use lower resolution for pure vector rendering. Closest resolution otherwise.
|
||||||
this.zDirection =
|
this.zDirection =
|
||||||
layer.getRenderMode() == ol.layer.VectorTileRenderType.VECTOR ? 1 : 0;
|
layer.getRenderMode() == ol.layer.VectorTileRenderType.VECTOR ? 1 : 0;
|
||||||
|
|
||||||
|
ol.events.listen(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
|
||||||
|
|
||||||
};
|
};
|
||||||
ol.inherits(ol.renderer.canvas.VectorTileLayer, ol.renderer.canvas.TileLayer);
|
ol.inherits(ol.renderer.canvas.VectorTileLayer, ol.renderer.canvas.TileLayer);
|
||||||
|
|
||||||
@@ -109,6 +114,15 @@ ol.renderer.canvas.VectorTileLayer.VECTOR_REPLAYS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.VectorTileLayer.prototype.disposeInternal = function() {
|
||||||
|
ol.events.unlisten(ol.render.canvas.labelCache, ol.events.EventType.CLEAR, this.handleFontsChanged_, this);
|
||||||
|
ol.renderer.canvas.TileLayer.prototype.disposeInternal.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -334,6 +348,17 @@ ol.renderer.canvas.VectorTileLayer.prototype.getReplayTransform_ = function(tile
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.events.Event} event Event.
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.VectorTileLayer.prototype.handleFontsChanged_ = function(event) {
|
||||||
|
var layer = this.getLayer();
|
||||||
|
if (layer.getVisible() && this.renderedLayerRevision_ !== undefined) {
|
||||||
|
layer.changed();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle changes in image style state.
|
* Handle changes in image style state.
|
||||||
* @param {ol.events.Event} event Image style change event.
|
* @param {ol.events.Event} event Image style change event.
|
||||||
@@ -443,7 +468,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, s
|
|||||||
} else {
|
} else {
|
||||||
loading = ol.renderer.vector.renderFeature(
|
loading = ol.renderer.vector.renderFeature(
|
||||||
replayGroup, feature, styles, squaredTolerance,
|
replayGroup, feature, styles, squaredTolerance,
|
||||||
this.handleStyleImageChange_, this) || loading;
|
this.handleStyleImageChange_, this);
|
||||||
}
|
}
|
||||||
return loading;
|
return loading;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ ol.renderer.vector.renderFeature = function(
|
|||||||
}
|
}
|
||||||
ol.renderer.vector.renderFeature_(replayGroup, feature, style,
|
ol.renderer.vector.renderFeature_(replayGroup, feature, style,
|
||||||
squaredTolerance);
|
squaredTolerance);
|
||||||
|
|
||||||
return loading;
|
return loading;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
goog.provide('ol.structs.LRUCache');
|
goog.provide('ol.structs.LRUCache');
|
||||||
|
|
||||||
|
goog.require('ol');
|
||||||
goog.require('ol.asserts');
|
goog.require('ol.asserts');
|
||||||
|
goog.require('ol.events.EventTarget');
|
||||||
|
goog.require('ol.events.EventType');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8,12 +11,16 @@ goog.require('ol.asserts');
|
|||||||
* Object's properties (e.g. 'hasOwnProperty' is not allowed as a key). Expiring
|
* Object's properties (e.g. 'hasOwnProperty' is not allowed as a key). Expiring
|
||||||
* items from the cache is the responsibility of the user.
|
* items from the cache is the responsibility of the user.
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @extends {ol.events.EventTarget}
|
||||||
|
* @fires ol.events.Event
|
||||||
* @struct
|
* @struct
|
||||||
* @template T
|
* @template T
|
||||||
* @param {number=} opt_highWaterMark High water mark.
|
* @param {number=} opt_highWaterMark High water mark.
|
||||||
*/
|
*/
|
||||||
ol.structs.LRUCache = function(opt_highWaterMark) {
|
ol.structs.LRUCache = function(opt_highWaterMark) {
|
||||||
|
|
||||||
|
ol.events.EventTarget.call(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
@@ -45,6 +52,8 @@ ol.structs.LRUCache = function(opt_highWaterMark) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ol.inherits(ol.structs.LRUCache, ol.events.EventTarget);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {boolean} Can expire cache.
|
* @return {boolean} Can expire cache.
|
||||||
@@ -62,6 +71,7 @@ ol.structs.LRUCache.prototype.clear = function() {
|
|||||||
this.entries_ = {};
|
this.entries_ = {};
|
||||||
this.oldest_ = null;
|
this.oldest_ = null;
|
||||||
this.newest_ = null;
|
this.newest_ = null;
|
||||||
|
this.dispatchEvent(ol.events.EventType.CLEAR);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -255,3 +265,15 @@ ol.structs.LRUCache.prototype.set = function(key, value) {
|
|||||||
this.entries_[key] = entry;
|
this.entries_[key] = entry;
|
||||||
++this.count_;
|
++this.count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} key Key.
|
||||||
|
* @param {T} value Value.
|
||||||
|
*/
|
||||||
|
ol.structs.LRUCache.prototype.pruneAndSet = function(key, value) {
|
||||||
|
while (this.canExpireCache()) {
|
||||||
|
this.pop();
|
||||||
|
}
|
||||||
|
this.set(key, value);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,10 +1,72 @@
|
|||||||
|
goog.require('ol.events');
|
||||||
|
goog.require('ol.obj');
|
||||||
goog.require('ol.render.canvas');
|
goog.require('ol.render.canvas');
|
||||||
|
|
||||||
|
|
||||||
describe('ol.render.canvas', function() {
|
describe('ol.render.canvas', function() {
|
||||||
|
|
||||||
|
var font = document.createElement('link');
|
||||||
|
font.href = 'https://fonts.googleapis.com/css?family=Inconsolata';
|
||||||
|
font.rel = 'stylesheet';
|
||||||
|
var head = document.getElementsByTagName('head')[0];
|
||||||
|
|
||||||
|
describe('ol.render.canvas.checkFont()', function() {
|
||||||
|
|
||||||
|
var checkFont = ol.render.canvas.checkFont;
|
||||||
|
|
||||||
|
it('does not clear the label cache for unavailable fonts', function(done) {
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
var spy = sinon.spy();
|
||||||
|
ol.events.listen(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
checkFont('12px foo,sans-serif');
|
||||||
|
setTimeout(function() {
|
||||||
|
ol.events.unlisten(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
expect(spy.callCount).to.be(0);
|
||||||
|
done();
|
||||||
|
}, 1600);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not clear the label cache for available fonts', function(done) {
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
var spy = sinon.spy();
|
||||||
|
ol.events.listen(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
checkFont('12px sans-serif');
|
||||||
|
setTimeout(function() {
|
||||||
|
ol.events.unlisten(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
expect(spy.callCount).to.be(0);
|
||||||
|
done();
|
||||||
|
}, 800);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not clear the label cache for the \'monospace\' font', function(done) {
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
var spy = sinon.spy();
|
||||||
|
ol.events.listen(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
checkFont('12px monospace');
|
||||||
|
setTimeout(function() {
|
||||||
|
ol.events.unlisten(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
expect(spy.callCount).to.be(0);
|
||||||
|
done();
|
||||||
|
}, 800);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clears the label cache for fonts that become available', function(done) {
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
head.appendChild(font);
|
||||||
|
var spy = sinon.spy();
|
||||||
|
ol.events.listen(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
checkFont('12px Inconsolata');
|
||||||
|
setTimeout(function() {
|
||||||
|
ol.events.unlisten(ol.render.canvas.labelCache, 'clear', spy);
|
||||||
|
head.removeChild(font);
|
||||||
|
expect(spy.callCount).to.be(1);
|
||||||
|
done();
|
||||||
|
}, 1600);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('rotateAtOffset', function() {
|
describe('rotateAtOffset', function() {
|
||||||
it('rotates a canvas at an offset point', function() {
|
it('rotates a canvas at an offset point', function() {
|
||||||
var context = {
|
var context = {
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ goog.require('ol.View');
|
|||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.geom.Point');
|
goog.require('ol.geom.Point');
|
||||||
goog.require('ol.layer.Vector');
|
goog.require('ol.layer.Vector');
|
||||||
|
goog.require('ol.obj');
|
||||||
goog.require('ol.proj');
|
goog.require('ol.proj');
|
||||||
|
goog.require('ol.render.canvas');
|
||||||
goog.require('ol.renderer.canvas.VectorLayer');
|
goog.require('ol.renderer.canvas.VectorLayer');
|
||||||
goog.require('ol.source.Vector');
|
goog.require('ol.source.Vector');
|
||||||
goog.require('ol.style.Style');
|
goog.require('ol.style.Style');
|
||||||
@@ -18,6 +20,24 @@ describe('ol.renderer.canvas.VectorLayer', function() {
|
|||||||
|
|
||||||
describe('constructor', function() {
|
describe('constructor', function() {
|
||||||
|
|
||||||
|
var head = document.getElementsByTagName('head')[0];
|
||||||
|
var font = document.createElement('link');
|
||||||
|
font.href = 'https://fonts.googleapis.com/css?family=Droid+Sans';
|
||||||
|
font.rel = 'stylesheet';
|
||||||
|
|
||||||
|
var target;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
target = document.createElement('div');
|
||||||
|
target.style.width = '256px';
|
||||||
|
target.style.height = '256px';
|
||||||
|
document.body.appendChild(target);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
document.body.removeChild(target);
|
||||||
|
});
|
||||||
|
|
||||||
it('creates a new instance', function() {
|
it('creates a new instance', function() {
|
||||||
var layer = new ol.layer.Vector({
|
var layer = new ol.layer.Vector({
|
||||||
source: new ol.source.Vector()
|
source: new ol.source.Vector()
|
||||||
@@ -66,6 +86,101 @@ describe('ol.renderer.canvas.VectorLayer', function() {
|
|||||||
document.body.removeChild(target);
|
document.body.removeChild(target);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not re-render for unavailable fonts', function(done) {
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
var map = new ol.Map({
|
||||||
|
view: new ol.View({
|
||||||
|
center: [0, 0],
|
||||||
|
zoom: 0
|
||||||
|
}),
|
||||||
|
target: target
|
||||||
|
});
|
||||||
|
var layerStyle = new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'layer',
|
||||||
|
font: '12px "Unavailable Font",sans-serif'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var feature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||||
|
var layer = new ol.layer.Vector({
|
||||||
|
source: new ol.source.Vector({
|
||||||
|
features: [feature]
|
||||||
|
}),
|
||||||
|
style: layerStyle
|
||||||
|
});
|
||||||
|
map.addLayer(layer);
|
||||||
|
var revision = layer.getRevision();
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(layer.getRevision()).to.be(revision);
|
||||||
|
done();
|
||||||
|
}, 800);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not re-render for available fonts', function(done) {
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
var map = new ol.Map({
|
||||||
|
view: new ol.View({
|
||||||
|
center: [0, 0],
|
||||||
|
zoom: 0
|
||||||
|
}),
|
||||||
|
target: target
|
||||||
|
});
|
||||||
|
var layerStyle = new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'layer',
|
||||||
|
font: '12px sans-serif'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var feature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||||
|
var layer = new ol.layer.Vector({
|
||||||
|
source: new ol.source.Vector({
|
||||||
|
features: [feature]
|
||||||
|
}),
|
||||||
|
style: layerStyle
|
||||||
|
});
|
||||||
|
map.addLayer(layer);
|
||||||
|
var revision = layer.getRevision();
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(layer.getRevision()).to.be(revision);
|
||||||
|
done();
|
||||||
|
}, 800);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('re-renders for fonts that become available', function(done) {
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
head.appendChild(font);
|
||||||
|
var map = new ol.Map({
|
||||||
|
view: new ol.View({
|
||||||
|
center: [0, 0],
|
||||||
|
zoom: 0
|
||||||
|
}),
|
||||||
|
target: target
|
||||||
|
});
|
||||||
|
var layerStyle = new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'layer',
|
||||||
|
font: '12px "Droid Sans",sans-serif'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
var feature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||||
|
var layer = new ol.layer.Vector({
|
||||||
|
source: new ol.source.Vector({
|
||||||
|
features: [feature]
|
||||||
|
}),
|
||||||
|
style: layerStyle
|
||||||
|
});
|
||||||
|
map.addLayer(layer);
|
||||||
|
var revision = layer.getRevision();
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(layer.getRevision()).to.be(revision + 1);
|
||||||
|
head.removeChild(font);
|
||||||
|
done();
|
||||||
|
}, 1600);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#forEachFeatureAtCoordinate', function() {
|
describe('#forEachFeatureAtCoordinate', function() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
goog.require('ol');
|
goog.require('ol');
|
||||||
|
goog.require('ol.obj');
|
||||||
goog.require('ol.Feature');
|
goog.require('ol.Feature');
|
||||||
goog.require('ol.Map');
|
goog.require('ol.Map');
|
||||||
goog.require('ol.TileState');
|
goog.require('ol.TileState');
|
||||||
@@ -13,6 +14,7 @@ goog.require('ol.geom.Point');
|
|||||||
goog.require('ol.layer.VectorTile');
|
goog.require('ol.layer.VectorTile');
|
||||||
goog.require('ol.proj');
|
goog.require('ol.proj');
|
||||||
goog.require('ol.proj.Projection');
|
goog.require('ol.proj.Projection');
|
||||||
|
goog.require('ol.render.canvas');
|
||||||
goog.require('ol.render.Feature');
|
goog.require('ol.render.Feature');
|
||||||
goog.require('ol.renderer.canvas.VectorTileLayer');
|
goog.require('ol.renderer.canvas.VectorTileLayer');
|
||||||
goog.require('ol.source.VectorTile');
|
goog.require('ol.source.VectorTile');
|
||||||
@@ -25,7 +27,12 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
|
|||||||
|
|
||||||
describe('constructor', function() {
|
describe('constructor', function() {
|
||||||
|
|
||||||
var map, layer, source, feature1, feature2, feature3, target, tileCallback;
|
var head = document.getElementsByTagName('head')[0];
|
||||||
|
var font = document.createElement('link');
|
||||||
|
font.href = 'https://fonts.googleapis.com/css?family=Dancing+Script';
|
||||||
|
font.rel = 'stylesheet';
|
||||||
|
|
||||||
|
var map, layer, layerStyle, source, feature1, feature2, feature3, target, tileCallback;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
tileCallback = function() {};
|
tileCallback = function() {};
|
||||||
@@ -40,7 +47,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
|
|||||||
}),
|
}),
|
||||||
target: target
|
target: target
|
||||||
});
|
});
|
||||||
var layerStyle = [new ol.style.Style({
|
layerStyle = [new ol.style.Style({
|
||||||
text: new ol.style.Text({
|
text: new ol.style.Text({
|
||||||
text: 'layer'
|
text: 'layer'
|
||||||
})
|
})
|
||||||
@@ -147,6 +154,44 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
|
|||||||
spy.restore();
|
spy.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not re-render for unavailable fonts', function(done) {
|
||||||
|
map.renderSync();
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
layerStyle[0].getText().setFont('12px "Unavailable font",sans-serif');
|
||||||
|
layer.changed();
|
||||||
|
var revision = layer.getRevision();
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(layer.getRevision()).to.be(revision);
|
||||||
|
done();
|
||||||
|
}, 800);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not re-render for available fonts', function(done) {
|
||||||
|
map.renderSync();
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
layerStyle[0].getText().setFont('12px sans-serif');
|
||||||
|
layer.changed();
|
||||||
|
var revision = layer.getRevision();
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(layer.getRevision()).to.be(revision);
|
||||||
|
done();
|
||||||
|
}, 800);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('re-renders for fonts that become available', function(done) {
|
||||||
|
map.renderSync();
|
||||||
|
ol.obj.clear(ol.render.canvas.checkedFonts_);
|
||||||
|
head.appendChild(font);
|
||||||
|
layerStyle[0].getText().setFont('12px "Dancing Script",sans-serif');
|
||||||
|
layer.changed();
|
||||||
|
var revision = layer.getRevision();
|
||||||
|
setTimeout(function() {
|
||||||
|
head.removeChild(font);
|
||||||
|
expect(layer.getRevision()).to.be(revision + 1);
|
||||||
|
done();
|
||||||
|
}, 1600);
|
||||||
|
});
|
||||||
|
|
||||||
it('transforms geometries when tile and view projection are different', function() {
|
it('transforms geometries when tile and view projection are different', function() {
|
||||||
var tile;
|
var tile;
|
||||||
tileCallback = function(t) {
|
tileCallback = function(t) {
|
||||||
|
|||||||
Reference in New Issue
Block a user