Add tests, remove unused code, encapsulate repeated code in functions

This commit is contained in:
Andreas Hocevar
2016-02-15 01:35:20 +01:00
parent a109062b1f
commit 952b99742e
5 changed files with 120 additions and 63 deletions

View File

@@ -94,3 +94,18 @@ ol.render.canvas.defaultTextBaseline = 'middle';
* @type {number} * @type {number}
*/ */
ol.render.canvas.defaultLineWidth = 1; ol.render.canvas.defaultLineWidth = 1;
/**
* @param {CanvasRenderingContext2D} context Context.
* @param {number} rotation Rotation.
* @param {number} offsetX X offset.
* @param {number} offsetY Y offset.
*/
ol.render.canvas.rotateAtOffset = function(context, rotation, offsetX, offsetY) {
if (rotation !== 0) {
context.translate(offsetX, offsetY);
context.rotate(rotation);
context.translate(-offsetX, -offsetY);
}
};

View File

@@ -2,12 +2,11 @@ goog.provide('ol.renderer.canvas.Layer');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('goog.vec.Mat4'); goog.require('goog.vec.Mat4');
goog.require('ol.array');
goog.require('ol.dom');
goog.require('ol.extent'); goog.require('ol.extent');
goog.require('ol.layer.Layer'); goog.require('ol.layer.Layer');
goog.require('ol.render.Event'); goog.require('ol.render.Event');
goog.require('ol.render.EventType'); goog.require('ol.render.EventType');
goog.require('ol.render.canvas');
goog.require('ol.render.canvas.Immediate'); goog.require('ol.render.canvas.Immediate');
goog.require('ol.renderer.Layer'); goog.require('ol.renderer.Layer');
goog.require('ol.vec.Mat4'); goog.require('ol.vec.Mat4');
@@ -53,6 +52,7 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat
var pixelRatio = frameState.pixelRatio; var pixelRatio = frameState.pixelRatio;
var width = frameState.size[0] * pixelRatio; var width = frameState.size[0] * pixelRatio;
var height = frameState.size[1] * pixelRatio; var height = frameState.size[1] * pixelRatio;
var rotation = frameState.viewState.rotation;
var topLeft = ol.extent.getTopLeft(extent); var topLeft = ol.extent.getTopLeft(extent);
var topRight = ol.extent.getTopRight(extent); var topRight = ol.extent.getTopRight(extent);
var bottomRight = ol.extent.getBottomRight(extent); var bottomRight = ol.extent.getBottomRight(extent);
@@ -68,18 +68,14 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat
bottomLeft, bottomLeft); bottomLeft, bottomLeft);
context.save(); context.save();
context.translate(width / 2, height / 2); ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2);
context.rotate(-frameState.viewState.rotation);
context.translate(-width / 2, -height / 2);
context.beginPath(); context.beginPath();
context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio); context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio);
context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio); context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio);
context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio); context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio);
context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio); context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio);
context.clip(); context.clip();
context.translate(width / 2, height / 2); ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2);
context.rotate(frameState.viewState.rotation);
context.translate(-width / 2, -height / 2);
} }
var imageTransform = this.getImageTransform(); var imageTransform = this.getImageTransform();
@@ -121,9 +117,8 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = function(type, contex
if (layer.hasListener(type)) { if (layer.hasListener(type)) {
var width = frameState.size[0] * frameState.pixelRatio; var width = frameState.size[0] * frameState.pixelRatio;
var height = frameState.size[1] * frameState.pixelRatio; var height = frameState.size[1] * frameState.pixelRatio;
context.translate(width / 2, height / 2); var rotation = frameState.viewState.rotation;
context.rotate(-frameState.viewState.rotation); ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2);
context.translate(-width / 2, -height / 2);
var transform = opt_transform !== undefined ? var transform = opt_transform !== undefined ?
opt_transform : this.getTransform(frameState, 0); opt_transform : this.getTransform(frameState, 0);
var render = new ol.render.canvas.Immediate( var render = new ol.render.canvas.Immediate(
@@ -133,9 +128,7 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = function(type, contex
context, null); context, null);
layer.dispatchEvent(composeEvent); layer.dispatchEvent(composeEvent);
render.flush(); render.flush();
context.translate(width / 2, height / 2); ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2);
context.rotate(frameState.viewState.rotation);
context.translate(-width / 2, -height / 2);
} }
}; };
@@ -228,46 +221,3 @@ ol.renderer.canvas.Layer.prototype.getPixelOnCanvas = function(pixelOnMap, image
ol.vec.Mat4.multVec2(imageTransformInv, pixelOnMap, pixelOnCanvas); ol.vec.Mat4.multVec2(imageTransformInv, pixelOnMap, pixelOnCanvas);
return pixelOnCanvas; return pixelOnCanvas;
}; };
/**
* @param {ol.Size} size Size.
* @return {boolean} True when the canvas with the current size does not exceed
* the maximum dimensions.
*/
ol.renderer.canvas.Layer.testCanvasSize = (function() {
/**
* @type {CanvasRenderingContext2D}
*/
var context = null;
/**
* @type {ImageData}
*/
var imageData = null;
return function(size) {
if (!context) {
context = ol.dom.createCanvasContext2D(1, 1);
imageData = context.createImageData(1, 1);
var data = imageData.data;
data[0] = 42;
data[1] = 84;
data[2] = 126;
data[3] = 255;
}
var canvas = context.canvas;
var good = size[0] <= canvas.width && size[1] <= canvas.height;
if (!good) {
canvas.width = size[0];
canvas.height = size[1];
var x = size[0] - 1;
var y = size[1] - 1;
context.putImageData(imageData, x, y);
var result = context.getImageData(x, y, 1, 1);
good = ol.array.equals(imageData.data, result.data);
}
return good;
};
})();

View File

@@ -7,6 +7,7 @@ goog.require('ol.dom');
goog.require('ol.extent'); goog.require('ol.extent');
goog.require('ol.layer.Vector'); goog.require('ol.layer.Vector');
goog.require('ol.render.EventType'); goog.require('ol.render.EventType');
goog.require('ol.render.canvas');
goog.require('ol.render.canvas.ReplayGroup'); goog.require('ol.render.canvas.ReplayGroup');
goog.require('ol.renderer.canvas.Layer'); goog.require('ol.renderer.canvas.Layer');
goog.require('ol.renderer.vector'); goog.require('ol.renderer.vector');
@@ -108,9 +109,8 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
var width = frameState.size[0] * pixelRatio; var width = frameState.size[0] * pixelRatio;
var height = frameState.size[1] * pixelRatio; var height = frameState.size[1] * pixelRatio;
replayContext.translate(width / 2, height / 2); ol.render.canvas.rotateAtOffset(replayContext, -rotation,
replayContext.rotate(-rotation); width / 2, height / 2);
replayContext.translate(-width / 2, -height / 2);
replayGroup.replay(replayContext, pixelRatio, transform, rotation, replayGroup.replay(replayContext, pixelRatio, transform, rotation,
skippedFeatureUids); skippedFeatureUids);
if (vectorSource.getWrapX() && projection.canWrapX() && if (vectorSource.getWrapX() && projection.canWrapX() &&
@@ -140,9 +140,8 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
// restore original transform for render and compose events // restore original transform for render and compose events
transform = this.getTransform(frameState, 0); transform = this.getTransform(frameState, 0);
} }
replayContext.translate(width / 2, height / 2); ol.render.canvas.rotateAtOffset(replayContext, rotation,
replayContext.rotate(rotation); width / 2, height / 2);
replayContext.translate(-width / 2, -height / 2);
if (replayContext != context) { if (replayContext != context) {
this.dispatchRenderEvent(replayContext, frameState, transform); this.dispatchRenderEvent(replayContext, frameState, transform);

View File

@@ -0,0 +1,25 @@
goog.provide('ol.test.render.canvas');
describe('ol.render.canvas', function() {
describe('rotateAtOffset', function() {
it('rotates a canvas at an offset point', function() {
var context = {
translate: sinon.spy(),
rotate: sinon.spy()
};
ol.render.canvas.rotateAtOffset(context, Math.PI, 10, 10);
expect(context.translate.callCount).to.be(2);
expect(context.translate.firstCall.args).to.eql([10, 10]);
expect(context.translate.secondCall.args).to.eql([-10, -10]);
expect(context.rotate.callCount).to.be(1);
expect(context.rotate.firstCall.args).to.eql([Math.PI]);
});
});
});
goog.require('ol.render');
goog.require('ol.render.canvas');

View File

@@ -0,0 +1,68 @@
goog.provide('ol.test.renderer.canvas.Layer');
describe('ol.renderer.canvas.Layer', function() {
describe('#composeFrame()', function() {
it('clips to layer extent and draws image', function() {
var layer = new ol.layer.Image({
extent: [1, 2, 3, 4]
});
var renderer = new ol.renderer.canvas.Layer(layer);
var image = new Image();
image.width = 3;
image.height = 3;
renderer.getImage = function() {
return image;
};
var frameState = {
viewState: {
center: [2, 3],
resolution: 1,
rotation: 0
},
size: [10, 10],
pixelRatio: 1,
coordinateToPixelMatrix: goog.vec.Mat4.createNumber(),
pixelToCoordinateMatrix: goog.vec.Mat4.createNumber()
};
renderer.getImageTransform = function() {
return goog.vec.Mat4.createNumberIdentity();
}
ol.renderer.Map.prototype.calculateMatrices2D(frameState);
var layerState = layer.getLayerState();
var context = {
save: sinon.spy(),
restore: sinon.spy(),
translate: sinon.spy(),
rotate: sinon.spy(),
beginPath: sinon.spy(),
moveTo: sinon.spy(),
lineTo: sinon.spy(),
clip: sinon.spy(),
drawImage: sinon.spy()
}
renderer.composeFrame(frameState, layerState, context);
expect(context.save.callCount).to.be(1);
expect(context.translate.callCount).to.be(0);
expect(context.rotate.callCount).to.be(0);
expect(context.beginPath.callCount).to.be(1);
expect(context.moveTo.firstCall.args).to.eql([4, 4]);
expect(context.lineTo.firstCall.args).to.eql([6, 4]);
expect(context.lineTo.secondCall.args).to.eql([6, 6]);
expect(context.lineTo.thirdCall.args).to.eql([4, 6]);
expect(context.clip.callCount).to.be(1);
expect(context.drawImage.firstCall.args).to.eql(
[renderer.getImage(), 0, 0, 3, 3, 0, 0, 3, 3]);
expect(context.restore.callCount).to.be(1);
});
});
});
goog.require('ol.render.canvas');
goog.require('goog.vec.Mat4');
goog.require('ol.layer.Image');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.Layer');