Fix edge smoothing with rotation.

This commit is contained in:
Antoine Vandecreme 2016-01-23 18:40:53 -05:00
parent 0d43f7e01a
commit c639dd5123
3 changed files with 67 additions and 23 deletions

View File

@ -249,8 +249,9 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
this.canvas.width = viewportSize.x;
this.canvas.height = viewportSize.y;
if ( this.sketchCanvas !== null ) {
this.sketchCanvas.width = this.canvas.width;
this.sketchCanvas.height = this.canvas.height;
var sketchCanvasSize = this._calculateSketchCanvasSize();
this.sketchCanvas.width = sketchCanvasSize.x;
this.sketchCanvas.height = sketchCanvasSize.y;
}
}
this._clear();
@ -312,8 +313,9 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
if ( useSketch ) {
if (this.sketchCanvas === null) {
this.sketchCanvas = document.createElement( "canvas" );
this.sketchCanvas.width = this.canvas.width;
this.sketchCanvas.height = this.canvas.height;
var sketchCanvasSize = this._calculateSketchCanvasSize();
this.sketchCanvas.width = sketchCanvasSize.x;
this.sketchCanvas.height = sketchCanvasSize.y;
this.sketchContext = this.sketchCanvas.getContext( "2d" );
}
context = this.sketchContext;
@ -381,18 +383,27 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
translate :
new $.Point(0, 0);
var widthExt = 0;
var heightExt = 0;
if (translate) {
var widthDiff = this.sketchCanvas.width - this.canvas.width;
var heightDiff = this.sketchCanvas.height - this.canvas.height;
widthExt = Math.round(widthDiff / 2);
heightExt = Math.round(heightDiff / 2);
}
this.context.save();
this.context.globalAlpha = opacity;
this.context.drawImage(
this.sketchCanvas,
position.x,
position.y,
this.sketchCanvas.width * scale,
this.sketchCanvas.height * scale,
0,
0,
this.canvas.width,
this.canvas.height
position.x - widthExt * scale,
position.y - heightExt * scale,
(this.canvas.width + 2 * widthExt) * scale,
(this.canvas.height + 2 * heightExt) * scale,
-widthExt,
-heightExt,
this.canvas.width + 2 * widthExt,
this.canvas.height + 2 * heightExt
);
this.context.restore();
},
@ -498,6 +509,16 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
}
},
/**
* Get the canvas size
* @param {Boolean} sketch If set to true return the size of the sketch canvas
* @returns {OpenSeadragon.Point} The size of the canvas
*/
getCanvasSize: function(sketch) {
var canvas = this._getContext(sketch).canvas;
return new $.Point(canvas.width, canvas.height);
},
// private
_offsetForRotation: function(degrees, useSketch) {
var cx = this.canvas.width / 2;
@ -525,6 +546,18 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
x: viewportSize.x * pixelDensityRatio,
y: viewportSize.y * pixelDensityRatio
};
},
// private
_calculateSketchCanvasSize: function() {
var canvasSize = this._calculateCanvasSize();
var sketchCanvasSize = Math.ceil(Math.sqrt(
canvasSize.x * canvasSize.x +
canvasSize.y * canvasSize.y));
return {
x: sketchCanvasSize,
y: sketchCanvasSize
};
}
};

View File

@ -350,11 +350,11 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{
* @param {Number} [scale=1] - Scale to be applied to position.
* @return {OpenSeadragon.Point}
*/
getTranslationForEdgeSmoothing: function(scale) {
// The translation vector must have positive values, otherwise the image goes a bit off
// the sketch canvas to the top and left and we must use negative coordinates to repaint it
// to the main canvas. And FF does not like it. It crashes the viewer.
return new $.Point(1, 1).minus(
getTranslationForEdgeSmoothing: function(scale, canvasSize, sketchCanvasSize) {
var sketchCanvasDelta = new $.Point(
Math.ceil((sketchCanvasSize.x - canvasSize.x) / 2),
Math.ceil((sketchCanvasSize.y - canvasSize.y) / 2));
return sketchCanvasDelta.minus(
this.position
.times($.pixelDensityRatio)
.times(scale || 1)

View File

@ -1324,14 +1324,18 @@ function drawTiles( tiledImage, lastDrawn ) {
// So we have to composite them at ~100% and scale them up together.
useSketch = true;
sketchScale = tile.getScaleForEdgeSmoothing();
sketchTranslate = tile.getTranslationForEdgeSmoothing(sketchScale);
sketchTranslate = tile.getTranslationForEdgeSmoothing(sketchScale,
tiledImage._drawer.getCanvasSize(false),
tiledImage._drawer.getCanvasSize(true));
}
if ( useSketch ) {
tiledImage._drawer._clear( true );
}
if (tiledImage.viewport.degrees !== 0) {
// When scaling, we must rotate only when blending the sketch canvas to avoid
// interpolation
if (tiledImage.viewport.degrees !== 0 && !sketchScale) {
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, useSketch);
}
@ -1400,12 +1404,19 @@ function drawTiles( tiledImage, lastDrawn ) {
tiledImage._drawer.restoreContext( useSketch );
}
if (tiledImage.viewport.degrees !== 0) {
if (tiledImage.viewport.degrees !== 0 && !sketchScale) {
tiledImage._drawer._restoreRotationChanges(useSketch);
}
if (useSketch) {
var offsetForRotation = tiledImage.viewport.degrees !== 0 && sketchScale;
if (offsetForRotation) {
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, false);
}
tiledImage._drawer.blendSketch(tiledImage.opacity, sketchScale, sketchTranslate);
if (offsetForRotation) {
tiledImage._drawer._restoreRotationChanges(false);
}
}
drawDebugInfo( tiledImage, lastDrawn );
}