[Libreoffice-commits] online.git: Branch 'feature/calc-canvas' - 13 commits - loleaflet/css loleaflet/src

Dennis Francis (via logerrit) logerrit at kemper.freedesktop.org
Tue Aug 25 07:14:41 UTC 2020


Rebased ref, commits from common ancestor:
commit 5debd7858b567aed45c85b7c151d087819a20a44
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Tue Aug 25 12:01:51 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:52 2020 +0530

    specialize twips/core-pixels/css-pixels conversion methods
    
    Change-Id: Ifb0a67b938fdd34a06bb7e75832498d566247010

diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index a8cb72b64..b80786bf9 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -494,17 +494,16 @@ L.CalcTileLayer = BaseTileLayer.extend({
 			return;
 		}
 
-		var newWidthPx = newDocWidth / this._tileWidthTwips * this._tileSize;
-		var newHeightPx = newDocHeight / this._tileHeightTwips * this._tileSize;
+		var newSizePx = this._twipsToCorePixels(new L.Point(newDocWidth, newDocHeight));
 
 		var topLeft = this._map.unproject(new L.Point(0, 0));
-		var bottomRight = this._map.unproject(new L.Point(newWidthPx, newHeightPx));
+		var bottomRight = this._map.unproject(newSizePx);
 		this._map.setMaxBounds(new L.LatLngBounds(topLeft, bottomRight));
 
-		this._docPixelSize = {x: newWidthPx, y: newHeightPx};
+		this._docPixelSize = newSizePx.clone();
 		this._docWidthTwips = newDocWidth;
 		this._docHeightTwips = newDocHeight;
-		this._map.fire('docsize', {x: newWidthPx, y: newHeightPx});
+		this._map.fire('docsize', newSizePx.clone());
 	},
 
 	_onUpdateCurrentHeader: function() {
@@ -558,8 +557,9 @@ L.CalcTileLayer = BaseTileLayer.extend({
 			this._selectedPart = command.selectedPart;
 			this._viewId = parseInt(command.viewid);
 			var mapSize = this._map.getSize();
-			var width = this._docWidthTwips / this._tileWidthTwips * this._tileSize;
-			var height = this._docHeightTwips / this._tileHeightTwips * this._tileSize;
+			var sizePx = this._twipsToPixels(new L.Point(this._docWidthTwips, this._docHeightTwips));
+			var width = sizePx.x;
+			var height = sizePx.y;
 			if (width < mapSize.x || height < mapSize.y) {
 				width = Math.max(width, mapSize.x);
 				height = Math.max(height, mapSize.y);
diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 88e271431..35f23437a 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -158,16 +158,17 @@ L.CanvasTilePainter = L.Class.extend({
 		var tileBounds = new L.Bounds(tileTopLeft, tileTopLeft.add(ctx.tileSize));
 
 		for (var i = 0; i < ctx.paneBoundsList.length; ++i) {
-			var paneBounds = ctx.paneBoundsList[i];
+			var paneBounds = this._layer._cssBoundsToCore(ctx.paneBoundsList[i]);
+			var viewBounds = this._layer._cssBoundsToCore(ctx.viewBounds);
 
 			if (!paneBounds.intersects(tileBounds))
 				continue;
 
 			var topLeft = paneBounds.getTopLeft();
 			if (topLeft.x)
-				topLeft.x = ctx.viewBounds.min.x;
+				topLeft.x = viewBounds.min.x;
 			if (topLeft.y)
-				topLeft.y = ctx.viewBounds.min.y;
+				topLeft.y = viewBounds.min.y;
 
 			this._canvasCtx.save();
 			this._canvasCtx.scale(1, 1);
@@ -194,7 +195,7 @@ L.CanvasTilePainter = L.Class.extend({
 		if (!splitPanesContext) {
 			return;
 		}
-		var splitPos = splitPanesContext.getSplitPos();
+		var splitPos = this._layer._cssPixelsToCore(splitPanesContext.getSplitPos());
 		this._canvasCtx.save();
 		this._canvasCtx.scale(1, 1);
 		this._canvasCtx.strokeStyle = 'red';
@@ -497,8 +498,75 @@ L.CanvasTileLayer = L.TileLayer.extend({
 
 	_pxBoundsToTileRange: function (bounds) {
 		return new L.Bounds(
-			bounds.min.divideBy(this._tileSize).floor(),
-			bounds.max.divideBy(this._tileSize).floor());
+			this._cssPixelsToCore(bounds.min)._divideBy(this._tileSize)._floor(),
+			this._cssPixelsToCore(bounds.max)._divideBy(this._tileSize)._floor());
+	},
+
+	_getCoreZoomFactor: function () {
+		return new L.Point(
+			this._tileSize * 15.0 / this._tileWidthTwips,
+			this._tileSize * 15.0 / this._tileHeightTwips);
+	},
+
+	_corePixelsToCss: function (corePixels) {
+		var dpiScale = this.canvasDPIScale();
+		return corePixels.divideBy(dpiScale);
+	},
+
+	_cssPixelsToCore: function (cssPixels) {
+		var dpiScale = this.canvasDPIScale();
+		return cssPixels.multiplyBy(dpiScale);
+	},
+
+	_cssBoundsToCore: function (bounds) {
+		return new L.Bounds(
+			this._cssPixelsToCore(bounds.min),
+			this._cssPixelsToCore(bounds.max)
+		);
+	},
+
+	_twipsToCorePixels: function (twips) {
+		return new L.Point(
+			twips.x / this._tileWidthTwips * this._tileSize,
+			twips.y / this._tileHeightTwips * this._tileSize);
+	},
+
+	_corePixelsToTwips: function (corePixels) {
+		return new L.Point(
+			corePixels.x / this._tileSize * this._tileWidthTwips,
+			corePixels.y / this._tileSize * this._tileHeightTwips);
+	},
+
+	_twipsToCssPixels: function (twips) {
+		var dpiScale = this.canvasDPIScale();
+		return new L.Point(
+			twips.x / this._tileWidthTwips * this._tileSize / dpiScale,
+			twips.y / this._tileHeightTwips * this._tileSize / dpiScale);
+	},
+
+	_cssPixelsToTwips: function (pixels) {
+		var dpiScale = this.canvasDPIScale();
+		return new L.Point(
+			pixels.x * dpiScale / this._tileSize * this._tileWidthTwips,
+			pixels.y * dpiScale / this._tileSize * this._tileHeightTwips);
+	},
+
+	_twipsToLatLng: function (twips, zoom) {
+		var pixels = this._twipsToCssPixels(twips);
+		return this._map.unproject(pixels, zoom);
+	},
+
+	_latLngToTwips: function (latLng, zoom) {
+		var pixels = this._map.project(latLng, zoom);
+		return this._cssPixelsToTwips(pixels);
+	},
+
+	_twipsToPixels: function (twips) { // css pixels
+		return this._twipsToCssPixels(twips);
+	},
+
+	_pixelsToTwips: function (pixels) { // css pixels
+		return this._cssPixelsToTwips(pixels);
 	},
 
 	_twipsToCoords: function (twips) {
@@ -524,6 +592,48 @@ L.CanvasTileLayer = L.TileLayer.extend({
 		return true;
 	},
 
+	_updateMaxBounds: function (sizeChanged, extraSize, options, zoom) {
+		if (this._docWidthTwips === undefined || this._docHeightTwips === undefined) {
+			return;
+		}
+		if (!zoom) {
+			zoom = this._map.getZoom();
+		}
+
+		var dpiScale = this.canvasDPIScale();
+		var docPixelLimits = new L.Point(this._docWidthTwips / this.options.tileWidthTwips,
+			this._docHeightTwips / this.options.tileHeightTwips);
+		// docPixelLimits should be in csspx.
+		docPixelLimits = docPixelLimits.multiplyBy(this._tileSize / dpiScale);
+		var scale = this._map.getZoomScale(zoom, 10);
+		var topLeft = new L.Point(0, 0);
+		topLeft = this._map.unproject(topLeft.multiplyBy(scale));
+		var bottomRight = new L.Point(docPixelLimits.x, docPixelLimits.y);
+		bottomRight = bottomRight.multiplyBy(scale);
+		if (extraSize) {
+			// extraSize is unscaled.
+			bottomRight = bottomRight.add(extraSize);
+		}
+		bottomRight = this._map.unproject(bottomRight);
+
+		if (this._documentInfo === '' || sizeChanged) {
+			// we just got the first status so we need to center the document
+			this._map.setMaxBounds(new L.LatLngBounds(topLeft, bottomRight), options);
+			this._map.setDocBounds(new L.LatLngBounds(topLeft, this._map.unproject(docPixelLimits.multiplyBy(scale))));
+		}
+
+		var scrollPixelLimits = new L.Point(this._docWidthTwips / this._tileWidthTwips,
+			this._docHeightTwips / this._tileHeightTwips);
+		scrollPixelLimits = scrollPixelLimits.multiplyBy(this._tileSize / dpiScale);
+		if (extraSize) {
+			// extraSize is unscaled.
+			scrollPixelLimits = scrollPixelLimits.add(extraSize);
+		}
+		this._docPixelSize = {x: scrollPixelLimits.x, y: scrollPixelLimits.y};
+		this._map.fire('docsize', {x: scrollPixelLimits.x, y: scrollPixelLimits.y, extraSize: extraSize});
+	},
+
+
 	_update: function (center, zoom) {
 		var map = this._map;
 		if (!map || this._documentInfo === '') {
@@ -1048,6 +1158,8 @@ L.CanvasTileLayer = L.TileLayer.extend({
 
 		var nwPoint = new L.Point(coords.x, coords.y);
 		var sePoint = nwPoint.add([tileSize, tileSize]);
+		nwPoint = this._corePixelsToCss(nwPoint);
+		sePoint = this._corePixelsToCss(sePoint);
 
 		var nw = map.wrapLatLng(map.unproject(nwPoint, coords.z));
 		var se = map.wrapLatLng(map.unproject(sePoint, coords.z));
commit 64a4de7cf419518498295c47dd199524c056ab10
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Tue Aug 25 11:55:25 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:52 2020 +0530

    detect change in dpi and update zoom
    
    Change-Id: I034727a8fe8495445350648fea2422c56fda1875

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 2a28a3e9e..88e271431 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -210,6 +210,14 @@ L.CanvasTilePainter = L.Class.extend({
 
 	update: function () {
 
+		var newDpiScale = L.getDpiScaleFactor(true /* useExactDPR */);
+		var scaleChanged = this._dpiScale != newDpiScale;
+
+		if (scaleChanged) {
+			this._dpiScale = L.getDpiScaleFactor(true /* useExactDPR */);
+			this._map.setZoom();
+		}
+
 		var splitPanesContext = this._layer.getSplitPanesContext();
 		var zoom = Math.round(this._map.getZoom());
 		var pixelBounds = this._map.getPixelBounds();
@@ -218,11 +226,9 @@ L.CanvasTilePainter = L.Class.extend({
 		var part = this._layer._selectedPart;
 		var newSplitPos = splitPanesContext ?
 		    splitPanesContext.getSplitPos(): this._splitPos;
-		var newDpiScale = L.getDpiScaleFactor(true /* useExactDPR */);
 
 		var zoomChanged = (zoom !== this._lastZoom);
 		var partChanged = (part !== this._lastPart);
-		var scaleChanged = this._dpiScale != newDpiScale;
 
 		var mapSizeChanged = !newMapSize.equals(this._lastMapSize);
 		// To avoid flicker, only resize the canvas element if width or height of the map increases.
@@ -246,11 +252,6 @@ L.CanvasTilePainter = L.Class.extend({
 		if (skipUpdate)
 			return;
 
-		if (scaleChanged) {
-			this._dpiScale = L.getDpiScaleFactor(true /* useExactDPR */);
-			console.log('DEBUG: scaleChanged : this._dpiScale = ' + this._dpiScale);
-		}
-
 		if (resizeCanvas || scaleChanged) {
 			this._setCanvasSize(newSize.x, newSize.y);
 			this._lastSize = newSize;
@@ -384,12 +385,8 @@ L.CanvasTileLayer = L.TileLayer.extend({
 		this._tileHeightPx = this.options.tileSize;
 		this._tilePixelScale = 1;
 
-		// FIXME: workaround for correcting initial zoom with dpiscale included.
-		// The one set during Map constructor is does not include dpiscale because
-		// there we don't have enough info to specialize for calc-canvas
-		map.setZoom(map.getZoom());
-
 		L.TileLayer.prototype.onAdd.call(this, map);
+		map.setZoom();
 	},
 
 	onRemove: function (map) {
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 0592c801d..8c3271b95 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -476,8 +476,14 @@ L.Map = L.Evented.extend({
 
 	setZoom: function (zoom, options) {
 
-		if (this._docLayer instanceof L.CanvasTileLayer)
+		if (this._docLayer instanceof L.CanvasTileLayer) {
+			if (!zoom)
+				zoom = this._clientZoom || this.options.zoom;
+			else
+				this._clientZoom = zoom;
+
 			zoom = this.findNearestProductZoom(zoom);
+		}
 
 		if (!this._loaded) {
 			this._zoom = this._limitZoom(zoom);
commit 08b9b023668d31eb1a6ec34e75a3d67efec20d54
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Tue Aug 25 11:36:03 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:52 2020 +0530

    use the main canvas dpiScale everywhere
    
    Change-Id: I2bea44a000552ce8f2fee2b0ebb5a4d162d3576f

diff --git a/loleaflet/src/control/Control.ColumnHeader.js b/loleaflet/src/control/Control.ColumnHeader.js
index 53ae8b9f2..df70e6cb7 100644
--- a/loleaflet/src/control/Control.ColumnHeader.js
+++ b/loleaflet/src/control/Control.ColumnHeader.js
@@ -39,7 +39,7 @@ L.Control.ColumnHeader = L.Control.Header.extend({
 		this._setCanvasHeight();
 		this._canvasBaseHeight = this._canvasHeight;
 
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 		this._canvasContext.scale(scale, scale);
 
 		this._headerHeight = this._canvasHeight;
@@ -224,8 +224,7 @@ L.Control.ColumnHeader = L.Control.Header.extend({
 			return;
 
 		ctx.save();
-		var useExactDPR = this._map && (this._map._docLayer instanceof L.CanvasTileLayer);
-		var scale = L.getDpiScaleFactor(useExactDPR);
+		var scale = this.canvasDPIScale();
 		ctx.scale(scale, scale);
 		// background gradient
 		var selectionBackgroundGradient = null;
@@ -291,7 +290,7 @@ L.Control.ColumnHeader = L.Control.Header.extend({
 		var height = group.endPos - group.startPos;
 
 		ctx.save();
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 		ctx.scale(scale, scale);
 
 		// clip mask
@@ -340,7 +339,7 @@ L.Control.ColumnHeader = L.Control.Header.extend({
 		var ctx = this._cornerCanvasContext;
 		var ctrlHeadSize = this._groupHeadSize;
 		var levelSpacing = this._levelSpacing;
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 
 		var startOrt = levelSpacing + (ctrlHeadSize + levelSpacing) * level;
 		var startPar = this._cornerCanvas.width / scale - (ctrlHeadSize + (L.Control.Header.rowHeaderWidth - ctrlHeadSize) / 2);
@@ -533,7 +532,7 @@ L.Control.ColumnHeader = L.Control.Header.extend({
 			return;
 		}
 
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 		var rowOutlineWidth = this._cornerCanvas.width / scale - L.Control.Header.rowHeaderWidth - this._borderWidth;
 		if (pos.x <= rowOutlineWidth) {
 			// empty rectangle on the left select all
diff --git a/loleaflet/src/control/Control.Header.js b/loleaflet/src/control/Control.Header.js
index 757cfd5c8..89fc78fe0 100644
--- a/loleaflet/src/control/Control.Header.js
+++ b/loleaflet/src/control/Control.Header.js
@@ -578,8 +578,13 @@ L.Control.Header = L.Control.extend({
 		return Math.round(this._getParallelPos(this.converter(point)));
 	},
 
+	canvasDPIScale: function () {
+		var docLayer = this._map && this._map._docLayer;
+		var scale = docLayer && docLayer.canvasDPIScale ? docLayer.canvasDPIScale() : L.getDpiScaleFactor();
+		return scale;
+	},
+
 	_setCanvasSizeImpl: function (container, canvas, property, value, isCorner) {
-		var useExactDPR = this._map && (this._map._docLayer instanceof L.CanvasTileLayer);
 		if (!value) {
 			value = parseInt(L.DomUtil.getStyle(container, property));
 		}
@@ -587,15 +592,15 @@ L.Control.Header = L.Control.extend({
 			L.DomUtil.setStyle(container, property, value + 'px');
 		}
 
-		var scale = L.getDpiScaleFactor(useExactDPR);
+		var scale = this.canvasDPIScale();
 		if (property === 'width') {
-			canvas.width = value * scale;
+			canvas.width = Math.floor(value * scale);
 			if (!isCorner)
 				this._canvasWidth = value;
 //			console.log('Header._setCanvasSizeImpl: _canvasWidth' + this._canvasWidth);
 		}
 		else if (property === 'height') {
-			canvas.height = value * scale;
+			canvas.height = Math.floor(value * scale);
 			if (!isCorner)
 				this._canvasHeight = value;
 //			console.log('Header._setCanvasSizeImpl: _canvasHeight' + this._canvasHeight);
@@ -718,7 +723,7 @@ L.Control.Header = L.Control.extend({
 			return;
 
 		ctx.save();
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 		ctx.scale(scale, scale);
 
 		ctx.fillStyle = this._borderColor;
diff --git a/loleaflet/src/control/Control.RowHeader.js b/loleaflet/src/control/Control.RowHeader.js
index 32974d9e9..2f42023be 100644
--- a/loleaflet/src/control/Control.RowHeader.js
+++ b/loleaflet/src/control/Control.RowHeader.js
@@ -39,7 +39,7 @@ L.Control.RowHeader = L.Control.Header.extend({
 		this._setCanvasWidth();
 		this._setCanvasHeight();
 
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 		this._canvasContext.scale(scale, scale);
 		this._headerWidth = this._canvasWidth;
 		L.Control.Header.rowHeaderWidth = this._canvasWidth;
@@ -217,8 +217,7 @@ L.Control.RowHeader = L.Control.Header.extend({
 			return;
 
 		ctx.save();
-		var useExactDPR = this._map && (this._map._docLayer instanceof L.CanvasTileLayer);
-		var scale = L.getDpiScaleFactor(useExactDPR);
+		var scale = this.canvasDPIScale();
 		ctx.scale(scale, scale);
 		// background gradient
 		var selectionBackgroundGradient = null;
@@ -280,7 +279,7 @@ L.Control.RowHeader = L.Control.Header.extend({
 		var height = group.endPos - group.startPos;
 
 		ctx.save();
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 		ctx.scale(scale, scale);
 
 		// clip mask
@@ -329,7 +328,7 @@ L.Control.RowHeader = L.Control.Header.extend({
 		var ctx = this._cornerCanvasContext;
 		var ctrlHeadSize = this._groupHeadSize;
 		var levelSpacing = this._levelSpacing;
-		var scale = L.getDpiScaleFactor();
+		var scale = this.canvasDPIScale();
 
 		var startOrt = levelSpacing + (ctrlHeadSize + levelSpacing) * level;
 		var startPar = this._cornerCanvas.height / scale - (ctrlHeadSize + (L.Control.Header.colHeaderHeight - ctrlHeadSize) / 2);
diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 8a77cf2a8..a8cb72b64 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -79,7 +79,6 @@ L.CalcTileLayer = BaseTileLayer.extend({
 	},
 
 	onAdd: function (map) {
-		this._useExactDPR = this._hasCanvasRenderer = (this instanceof L.CanvasTileLayer);
 		map.addControl(L.control.tabs());
 		map.addControl(L.control.columnHeader());
 		map.addControl(L.control.rowHeader());
@@ -468,7 +467,7 @@ L.CalcTileLayer = BaseTileLayer.extend({
 		this._sendClientZoom();
 		if (this.sheetGeometry) {
 			this.sheetGeometry.setTileGeometryData(this._tileWidthTwips, this._tileHeightTwips,
-				this._tileSize, this._hasCanvasRenderer ? L.getDpiScaleFactor(true /* useExactDPR */) : this._tilePixelScale);
+				this._tileSize, this.hasCanvasRenderer() ? this.canvasDPIScale() : this._tilePixelScale);
 		}
 		this._restrictDocumentSize();
 		this._replayPrintTwipsMsgs();
@@ -734,7 +733,7 @@ L.CalcTileLayer = BaseTileLayer.extend({
 	_handleSheetGeometryDataMsg: function (jsonMsgObj) {
 		if (!this.sheetGeometry) {
 			this._sheetGeomFirstWait = false;
-			var dpiScale = this._hasCanvasRenderer ? L.getDpiScaleFactor(true /* useExactDPR */) : this._tilePixelScale;
+			var dpiScale = this.hasCanvasRenderer() ? this.canvasDPIScale() : this._tilePixelScale;
 			this.sheetGeometry = new L.SheetGeometry(jsonMsgObj,
 				this._tileWidthTwips, this._tileHeightTwips,
 				this._tileSize, dpiScale, this._selectedPart);
diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index f8b739a2a..2a28a3e9e 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -111,6 +111,10 @@ L.CanvasTilePainter = L.Class.extend({
 		this._syncTileContainerSize();
 	},
 
+	canvasDPIScale: function () {
+		return parseInt(this._canvas.width) / this._width;
+	},
+
 	_syncTileContainerSize: function () {
 		var tileContainer = this._layer._container;
 		if (tileContainer) {
@@ -481,6 +485,10 @@ L.CanvasTileLayer = L.TileLayer.extend({
 			coords.part);
 	},
 
+	canvasDPIScale: function () {
+		return this._painter.canvasDPIScale();
+	},
+
 	_pxBoundsToTileRanges: function (bounds) {
 		if (!this._splitPanesContext) {
 			return [this._pxBoundsToTileRange(bounds)];
@@ -1210,6 +1218,10 @@ L.CanvasTileLayer = L.TileLayer.extend({
 		return !!(this._ySplitter);
 	},
 
+	hasCanvasRenderer: function () {
+		return true;
+	},
+
 });
 
 L.TilesPreFetcher = L.Class.extend({
diff --git a/loleaflet/src/layer/tile/GridLayer.js b/loleaflet/src/layer/tile/GridLayer.js
index 5d3ce69db..4ad07d8fa 100644
--- a/loleaflet/src/layer/tile/GridLayer.js
+++ b/loleaflet/src/layer/tile/GridLayer.js
@@ -1352,6 +1352,10 @@ L.GridLayer = L.Layer.extend({
 		return docPosPixY;
 	},
 
+	hasCanvasRenderer: function () {
+		return false;
+	},
+
 	hasSplitPanesSupport: function () {
 		return false;
 	},
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 946896e0c..0592c801d 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -452,12 +452,23 @@ L.Map = L.Evented.extend({
 		this._progressBar.end(this);
 	},
 
+	zoomToFactor: function (zoom) {
+		return Math.pow(1.2, (zoom - this.options.zoom));
+	},
+
+	factorToZoom: function (zoomFactor) {
+		var relzoom = Math.log(zoomFactor) / Math.log(1.2);
+		return Math.round(relzoom) + this.options.zoom;
+	},
+
 	// Compute the nearest zoom level corresponding to the effective zoom-scale (ie, with dpiscale included).
 	findNearestProductZoom: function (zoom) {
-		var clientZoomScale = Math.pow(1.2, (zoom - this.options.zoom));
+		var clientZoomScale = this.zoomToFactor(zoom);
+
+		var dpiScale = this._docLayer ? this._docLayer.canvasDPIScale() : L.getDpiScaleFactor(true /* useExactDPR */);
 
-		var zoomScale = clientZoomScale * L.getCanvasScaleFactor();
-		var nearestZoom = Math.round((Math.log(zoomScale) / Math.log(1.2)) + this.options.zoom);
+		var zoomScale = clientZoomScale * dpiScale;
+		var nearestZoom = this.factorToZoom(zoomScale);
 		nearestZoom = this._limitZoom(nearestZoom);
 
 		return nearestZoom;
commit 5f042808917e0350014ea22811e8dcc9b51b89bb
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 22:34:27 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:52 2020 +0530

    sheetGeometry: use exact dpiScale when canvas is used
    
    Also use the term core-pixels instead of 'device pixels' which is more
    appropriate.
    
    Change-Id: I18952393f17e0391167e0219b829be47723c5c47

diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 3daa75e69..8a77cf2a8 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -79,6 +79,7 @@ L.CalcTileLayer = BaseTileLayer.extend({
 	},
 
 	onAdd: function (map) {
+		this._useExactDPR = this._hasCanvasRenderer = (this instanceof L.CanvasTileLayer);
 		map.addControl(L.control.tabs());
 		map.addControl(L.control.columnHeader());
 		map.addControl(L.control.rowHeader());
@@ -467,7 +468,7 @@ L.CalcTileLayer = BaseTileLayer.extend({
 		this._sendClientZoom();
 		if (this.sheetGeometry) {
 			this.sheetGeometry.setTileGeometryData(this._tileWidthTwips, this._tileHeightTwips,
-				this._tileSize, this._tilePixelScale);
+				this._tileSize, this._hasCanvasRenderer ? L.getDpiScaleFactor(true /* useExactDPR */) : this._tilePixelScale);
 		}
 		this._restrictDocumentSize();
 		this._replayPrintTwipsMsgs();
@@ -733,9 +734,10 @@ L.CalcTileLayer = BaseTileLayer.extend({
 	_handleSheetGeometryDataMsg: function (jsonMsgObj) {
 		if (!this.sheetGeometry) {
 			this._sheetGeomFirstWait = false;
+			var dpiScale = this._hasCanvasRenderer ? L.getDpiScaleFactor(true /* useExactDPR */) : this._tilePixelScale;
 			this.sheetGeometry = new L.SheetGeometry(jsonMsgObj,
 				this._tileWidthTwips, this._tileHeightTwips,
-				this._tileSize, this._tilePixelScale, this._selectedPart);
+				this._tileSize, dpiScale, this._selectedPart);
 		}
 		else {
 			this.sheetGeometry.update(jsonMsgObj, /* checkCompleteness */ false, this._selectedPart);
@@ -1215,12 +1217,12 @@ L.SheetGeometry = L.Class.extend({
 	// all flags (ie 'columns', 'rows', 'sizes', 'hidden', 'filtered',
 	// 'groups') enabled.
 	initialize: function (sheetGeomJSON, tileWidthTwips, tileHeightTwips,
-		tileSizeCSSPixels, dpiScale, part) {
+		tileSizePixels, dpiScale, part) {
 
 		if (typeof sheetGeomJSON !== 'object' ||
 			typeof tileWidthTwips !== 'number' ||
 			typeof tileHeightTwips !== 'number' ||
-			typeof tileSizeCSSPixels !== 'number' ||
+			typeof tileSizePixels !== 'number' ||
 			typeof dpiScale !== 'number' ||
 			typeof part !== 'number') {
 			console.error('Incorrect constructor argument types or missing required arguments');
@@ -1233,7 +1235,7 @@ L.SheetGeometry = L.Class.extend({
 		this._unoCommand = '.uno:SheetGeometryData';
 
 		// Set various unit conversion info early on because on update() call below, these info are needed.
-		this.setTileGeometryData(tileWidthTwips, tileHeightTwips, tileSizeCSSPixels,
+		this.setTileGeometryData(tileWidthTwips, tileHeightTwips, tileSizePixels,
 			dpiScale, false /* update position info ?*/);
 
 		this.update(sheetGeomJSON, /* checkCompleteness */ true, part);
@@ -1277,10 +1279,10 @@ L.SheetGeometry = L.Class.extend({
 		return this._part;
 	},
 
-	setTileGeometryData: function (tileWidthTwips, tileHeightTwips, tileSizeCSSPixels,
+	setTileGeometryData: function (tileWidthTwips, tileHeightTwips, tileSizePixels,
 		dpiScale, updatePositions) {
-		this._columns.setTileGeometryData(tileWidthTwips, tileSizeCSSPixels, dpiScale, updatePositions);
-		this._rows.setTileGeometryData(tileHeightTwips, tileSizeCSSPixels, dpiScale, updatePositions);
+		this._columns.setTileGeometryData(tileWidthTwips, tileSizePixels, dpiScale, updatePositions);
+		this._rows.setTileGeometryData(tileHeightTwips, tileSizePixels, dpiScale, updatePositions);
 	},
 
 	setViewArea: function (topLeftTwipsPoint, sizeTwips) {
@@ -1421,7 +1423,7 @@ L.SheetGeometry = L.Class.extend({
 	},
 
 	// Returns full sheet size as L.Point in the given unit.
-	// unit must be one of 'csspixels', 'devpixels', 'tiletwips', 'printtwips'
+	// unit must be one of 'csspixels', 'corepixels', 'tiletwips', 'printtwips'
 	getSize: function (unit) {
 		return new L.Point(this._columns.getSize(unit),
 			this._rows.getSize(unit));
@@ -1429,8 +1431,8 @@ L.SheetGeometry = L.Class.extend({
 
 	// Returns the CSS pixel position/size of the requested cell at a specified zoom.
 	getCellRect: function (columnIndex, rowIndex, zoomScale) {
-		var horizPosSize = this._columns.getElementData(columnIndex, false /* devicePixels */, zoomScale);
-		var vertPosSize  = this._rows.getElementData(rowIndex, false /* devicePixels */, zoomScale);
+		var horizPosSize = this._columns.getElementData(columnIndex, false /* corePixels */, zoomScale);
+		var vertPosSize  = this._rows.getElementData(rowIndex, false /* corePixels */, zoomScale);
 
 		var topLeft = new L.Point(horizPosSize.startpos, vertPosSize.startpos);
 		var size = new L.Point(horizPosSize.size, vertPosSize.size);
@@ -1447,13 +1449,13 @@ L.SheetGeometry = L.Class.extend({
 	},
 
 	// Returns the start position of the column containing posX in the specified unit.
-	// unit must be one of 'csspixels', 'devpixels', 'tiletwips', 'printtwips'
+	// unit must be one of 'csspixels', 'corepixels', 'tiletwips', 'printtwips'
 	getSnapDocPosX: function (posX, unit) {
 		return this._columns.getSnapPos(posX, unit);
 	},
 
 	// Returns the start position of the row containing posY in the specified unit.
-	// unit must be one of 'csspixels', 'devpixels', 'tiletwips', 'printtwips'
+	// unit must be one of 'csspixels', 'corepixels', 'tiletwips', 'printtwips'
 	getSnapDocPosY: function (posY, unit) {
 		return this._rows.getSnapPos(posY, unit);
 	},
@@ -1585,7 +1587,7 @@ L.SheetDimension = L.Class.extend({
 		this._maxIndex = maxIndex;
 	},
 
-	setTileGeometryData: function (tileSizeTwips, tileSizeCSSPixels, dpiScale, updatePositions) {
+	setTileGeometryData: function (tileSizeTwips, tileSizePixels, dpiScale, updatePositions) {
 
 		if (updatePositions === undefined) {
 			updatePositions = true;
@@ -1593,17 +1595,22 @@ L.SheetDimension = L.Class.extend({
 
 		// Avoid position re-computations if no change in Zoom/dpiScale.
 		if (this._tileSizeTwips === tileSizeTwips &&
-			this._tileSizeCSSPixels === tileSizeCSSPixels &&
+			this._tileSizePixels === tileSizePixels &&
 			this._dpiScale === dpiScale) {
 			return;
 		}
 
 		this._tileSizeTwips = tileSizeTwips;
-		this._tileSizeCSSPixels = tileSizeCSSPixels;
+		this._tileSizePixels = tileSizePixels;
 		this._dpiScale = dpiScale;
 
-		this._twipsPerCSSPixel = tileSizeTwips / tileSizeCSSPixels;
-		this._devPixelsPerCssPixel = dpiScale;
+		// number of core-pixels in the tile is the same as the number of device pixels used to render the tile.
+		// (Note that when not using L.CanvasTileLayer, we do not use the exact window.devicePixelRatio
+		// for dpiScale hence the usage of the term device-pixels is not accurate.)
+		this._coreZoomFactor = this._tileSizePixels * 15.0 / this._tileSizeTwips;
+		this._twipsPerCorePixel = this._tileSizeTwips / this._tileSizePixels;
+
+		this._corePixelsPerCssPixel = this._dpiScale;
 
 		if (updatePositions) {
 			// We need to compute positions data for every zoom change.
@@ -1620,7 +1627,7 @@ L.SheetDimension = L.Class.extend({
 
 	_updatePositions: function() {
 
-		var posDevPx = 0; // position in device pixels.
+		var posCorePx = 0; // position in core pixels.
 		var posPrintTwips = 0;
 		var dimensionObj = this;
 		this._visibleSizes.addCustomDataForEachSpan(function (
@@ -1628,17 +1635,17 @@ L.SheetDimension = L.Class.extend({
 			size, /* size in twips of one element in the span */
 			spanLength /* #elements in the span */) {
 
-			// Important: rounding needs to be done in device pixels exactly like the core.
-			var sizeDevPxOne = Math.floor(size / dimensionObj._twipsPerCSSPixel * dimensionObj._devPixelsPerCssPixel);
-			posDevPx += (sizeDevPxOne * spanLength);
-			var posCssPx = posDevPx / dimensionObj._devPixelsPerCssPixel;
-			// position in device-pixel aligned twips.
-			var posTileTwips = Math.floor(posCssPx * dimensionObj._twipsPerCSSPixel);
+			// Important: rounding needs to be done in core pixels to match core.
+			var sizeCorePxOne = Math.floor(size / dimensionObj._twipsPerCorePixel);
+			posCorePx += (sizeCorePxOne * spanLength);
+			var posCssPx = posCorePx / dimensionObj._corePixelsPerCssPixel;
+			// position in core-pixel aligned twips.
+			var posTileTwips = Math.floor(posCorePx * dimensionObj._twipsPerCorePixel);
 			posPrintTwips += (size * spanLength);
 
 			var customData = {
-				sizedev: sizeDevPxOne,
-				posdevpx: posDevPx,
+				sizecore: sizeCorePxOne,
+				poscorepx: posCorePx,
 				poscsspx: posCssPx,
 				postiletwips: posTileTwips,
 				posprinttwips: posPrintTwips
@@ -1649,23 +1656,29 @@ L.SheetDimension = L.Class.extend({
 	},
 
 	// returns the element pos/size in css pixels by default.
-	getElementData: function (index, useDevicePixels, zoomScale) {
+	getElementData: function (index, useCorePixels, zoomScale) {
 		if (zoomScale !== undefined) {
 			var startpos = 0;
 			var size = 0;
 			this._visibleSizes.forEachSpanInRange(0, index, function (spanData) {
 				var count = spanData.end - spanData.start + 1;
-				var sizeOneCSSPx = Math.floor(spanData.size * zoomScale / 15.0);
+				var sizeOneCorePx = Math.floor(spanData.size * zoomScale / 15.0);
 				if (index > spanData.end) {
-					startpos += (sizeOneCSSPx * count);
+					startpos += (sizeOneCorePx * count);
 				}
 				else if (index >= spanData.start && index <= spanData.end) {
 					// final span
-					startpos += (sizeOneCSSPx * (index - spanData.start));
-					size = sizeOneCSSPx;
+					startpos += (sizeOneCorePx * (index - spanData.start));
+					size = sizeOneCorePx;
 				}
 			});
 
+			if (!useCorePixels) {
+				// startpos and size are now in core pixels, so convert to css pixels.
+				startpos = Math.floor(startpos / this._corePixelsPerCssPixel);
+				size = Math.floor(size / this._corePixelsPerCssPixel);
+			}
+
 			return {
 				startpos: startpos,
 				size: size
@@ -1677,7 +1690,7 @@ L.SheetDimension = L.Class.extend({
 			return undefined;
 		}
 
-		return this._getElementDataFromSpanByIndex(index, span, useDevicePixels);
+		return this._getElementDataFromSpanByIndex(index, span, useCorePixels);
 	},
 
 	getElementDataAny: function (index, unitName) {
@@ -1690,9 +1703,9 @@ L.SheetDimension = L.Class.extend({
 	},
 
 	// returns element pos/size in css pixels by default.
-	_getElementDataFromSpanByIndex: function (index, span, useDevicePixels) {
+	_getElementDataFromSpanByIndex: function (index, span, useCorePixels) {
 		return this._getElementDataAnyFromSpanByIndex(index, span,
-				useDevicePixels ? 'devpixels' : 'csspixels');
+				useCorePixels ? 'corepixels' : 'csspixels');
 	},
 
 	// returns element pos/size in the requested unit.
@@ -1702,20 +1715,20 @@ L.SheetDimension = L.Class.extend({
 			return undefined;
 		}
 
-		if (unitName !== 'csspixels' && unitName !== 'devpixels' &&
+		if (unitName !== 'csspixels' && unitName !== 'corepixels' &&
 				unitName !== 'tiletwips' && unitName !== 'printtwips') {
 			console.error('unsupported unitName: ' + unitName);
 			return undefined;
 		}
 
 		var numSizes = span.end - index + 1;
-		var inPixels = (unitName === 'csspixels' || unitName === 'devpixels');
+		var inPixels = (unitName === 'csspixels' || unitName === 'corepixels');
 		if (inPixels) {
-			var useDevicePixels = (unitName === 'devpixels');
-			var pixelScale = useDevicePixels ? 1 : this._devPixelsPerCssPixel;
+			var useCorePixels = (unitName === 'corepixels');
+			var pixelScale = useCorePixels ? 1 : this._corePixelsPerCssPixel;
 			return {
-				startpos: (span.data.posdevpx - span.data.sizedev * numSizes) / pixelScale,
-				size: span.data.sizedev / pixelScale
+				startpos: (span.data.poscorepx - span.data.sizecore * numSizes) / pixelScale,
+				size: span.data.sizecore / pixelScale
 			};
 		}
 
@@ -1727,12 +1740,12 @@ L.SheetDimension = L.Class.extend({
 		}
 
 		// unitName is 'tiletwips'
-		// It is very important to calculate this from device pixel units to mirror the core calculations.
-		var twipsPerDevPixels = this._twipsPerCSSPixel / this._devPixelsPerCssPixel;
+		// It is very important to calculate this from core pixel units to mirror the core calculations.
+		var twipsPerCorePixel = this._twipsPerCorePixel;
 		return {
 			startpos: Math.floor(
-				(span.data.posdevpx - span.data.sizedev * numSizes) * twipsPerDevPixels),
-			size: Math.floor(span.data.sizedev * twipsPerDevPixels)
+				(span.data.poscorepx - span.data.sizecore * numSizes) * twipsPerCorePixel),
+			size: Math.floor(span.data.sizecore * twipsPerCorePixel)
 		};
 	},
 
@@ -1761,8 +1774,7 @@ L.SheetDimension = L.Class.extend({
 			return result;
 		}
 		var elementCount = span.end - span.start + 1;
-		var posStart = ((span.data.posdevpx - span.data.sizedev * elementCount) /
-			this._devPixelsPerCssPixel * this._twipsPerCSSPixel);
+		var posStart = ((span.data.poscorepx - span.data.sizecore * elementCount) * this._twipsPerCorePixel);
 		var posEnd = span.data.postiletwips;
 		var sizeOne = (posEnd - posStart) / elementCount;
 
@@ -1829,8 +1841,8 @@ L.SheetDimension = L.Class.extend({
 		this._outlines.forEachGroupInRange(this._viewStartIndex, this._viewEndIndex,
 			function (levelIdx, groupIdx, start, end, hidden) {
 
-				var startElementData = dimensionObj.getElementData(start, true /* device pixels */);
-				var endElementData = dimensionObj.getElementData(end, true /* device pixels */);
+				var startElementData = dimensionObj.getElementData(start, true /* core pixels */);
+				var endElementData = dimensionObj.getElementData(end, true /* core pixels */);
 				groupsData.push({
 					level: (levelIdx + 1).toString(),
 					index: groupIdx.toString(),
@@ -1892,9 +1904,9 @@ L.SheetDimension = L.Class.extend({
 		var startData = this._getElementDataAnyFromSpanByIndex(startElement.index, startElement.span, 'tiletwips');
 		if (posStartPT === posEndPT) {
 			// range is hidden, send a minimal sized tile-twips range.
-			// Set the size = twips equivalent of 1 device pixel,
+			// Set the size = twips equivalent of 1 core pixel,
 			// to imitate what core does when it sends cursor/ranges in tile-twips coordinates.
-			var rangeSize = Math.floor(this._twipsPerCSSPixel / this._devPixelsPerCssPixel);
+			var rangeSize = Math.floor(this._twipsPerCorePixel);
 			return {
 				startpos: startData.startpos,
 				endpos: startData.startpos + rangeSize
@@ -1927,7 +1939,7 @@ L.SheetDimension = L.Class.extend({
 	isUnitSupported: function (unitName) {
 		return (
 			unitName === 'csspixels' ||
-			unitName === 'devpixels' ||
+			unitName === 'corepixels' ||
 			unitName === 'tiletwips' ||
 			unitName === 'printtwips'
 		);
@@ -1939,12 +1951,12 @@ L.SheetDimension = L.Class.extend({
 
 		var origUnit = unit;
 
-		if (unit === 'devpixels') {
-			pos = (pos * this._twipsPerCSSPixel) / this._devPixelsPerCssPixel;
+		if (unit === 'corepixels') {
+			pos = pos * this._twipsPerCorePixel;
 			unit = 'tiletwips';
 		}
 		else if (unit === 'csspixels') {
-			pos = pos * this._twipsPerCSSPixel;
+			pos = pos * this._corePixelsPerCssPixel * this._twipsPerCorePixel;
 			unit = 'tiletwips';
 		}
 
@@ -1960,12 +1972,12 @@ L.SheetDimension = L.Class.extend({
 		console.assert(typeof pos === 'number', 'pos is not a number');
 		console.assert(this.isUnitSupported(unit), 'unit: ' + unit + ' is not supported');
 
-		if (unit === 'devpixels') {
-			pos = (pos * this._twipsPerCSSPixel) / this._devPixelsPerCssPixel;
+		if (unit === 'corepixels') {
+			pos = pos * this._twipsPerCorePixel;
 			unit = 'tiletwips';
 		}
 		else if (unit === 'csspixels') {
-			pos = pos * this._twipsPerCSSPixel;
+			pos = pos * this._corePixelsPerCssPixel * this._twipsPerCorePixel;
 			unit = 'tiletwips';
 		}
 
commit 3fe33cf12068a93cec891316dd7fdacb69792c7f
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 22:31:16 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    header canvases should resize with map-resize
    
    This is now safe as we update their contents on resize.
    
    Change-Id: Ie8b33e03e9b67de0f5c4d0e4822154032c171a70

diff --git a/loleaflet/css/spreadsheet.css b/loleaflet/css/spreadsheet.css
index c0c6b95e0..abf6cad98 100644
--- a/loleaflet/css/spreadsheet.css
+++ b/loleaflet/css/spreadsheet.css
@@ -130,6 +130,7 @@
 .spreadsheet-header-columns {
 	display: inline-block;
 	white-space: nowrap;
+	width: 100%;
 	height: 100%;
 	border-spacing: 0px !important;
 	position: relative;
@@ -172,6 +173,7 @@
 
 .spreadsheet-header-rows {
 	width: 100%;
+	height: 100%;
 	border-spacing: 0px !important;
 	position: relative;
 	margin: 0px;
commit bd35d82d79791e22fddbd5802366ed70e8968ac0
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 22:12:18 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    setup the header canvases in the same way as the tile-canvas
    
    All drawings to it needs to in css pixels for now, because the
    mouse/touch handlers need positions in css pixels and the HeaderInfo
    datastructure has everything in css pixels.
    
    Moving the headers to the main-canvas needs more work but this change
    will help in doing that.
    
    Change-Id: I6a19e62a67b2b42975a51bb695db300ce493ba01

diff --git a/loleaflet/src/control/Control.ColumnHeader.js b/loleaflet/src/control/Control.ColumnHeader.js
index cbd73c919..53ae8b9f2 100644
--- a/loleaflet/src/control/Control.ColumnHeader.js
+++ b/loleaflet/src/control/Control.ColumnHeader.js
@@ -224,7 +224,8 @@ L.Control.ColumnHeader = L.Control.Header.extend({
 			return;
 
 		ctx.save();
-		var scale = L.getDpiScaleFactor();
+		var useExactDPR = this._map && (this._map._docLayer instanceof L.CanvasTileLayer);
+		var scale = L.getDpiScaleFactor(useExactDPR);
 		ctx.scale(scale, scale);
 		// background gradient
 		var selectionBackgroundGradient = null;
diff --git a/loleaflet/src/control/Control.Header.js b/loleaflet/src/control/Control.Header.js
index bb0d4433f..757cfd5c8 100644
--- a/loleaflet/src/control/Control.Header.js
+++ b/loleaflet/src/control/Control.Header.js
@@ -579,6 +579,7 @@ L.Control.Header = L.Control.extend({
 	},
 
 	_setCanvasSizeImpl: function (container, canvas, property, value, isCorner) {
+		var useExactDPR = this._map && (this._map._docLayer instanceof L.CanvasTileLayer);
 		if (!value) {
 			value = parseInt(L.DomUtil.getStyle(container, property));
 		}
@@ -586,7 +587,7 @@ L.Control.Header = L.Control.extend({
 			L.DomUtil.setStyle(container, property, value + 'px');
 		}
 
-		var scale = L.getDpiScaleFactor();
+		var scale = L.getDpiScaleFactor(useExactDPR);
 		if (property === 'width') {
 			canvas.width = value * scale;
 			if (!isCorner)
diff --git a/loleaflet/src/control/Control.RowHeader.js b/loleaflet/src/control/Control.RowHeader.js
index e39162ff2..32974d9e9 100644
--- a/loleaflet/src/control/Control.RowHeader.js
+++ b/loleaflet/src/control/Control.RowHeader.js
@@ -217,7 +217,8 @@ L.Control.RowHeader = L.Control.Header.extend({
 			return;
 
 		ctx.save();
-		var scale = L.getDpiScaleFactor();
+		var useExactDPR = this._map && (this._map._docLayer instanceof L.CanvasTileLayer);
+		var scale = L.getDpiScaleFactor(useExactDPR);
 		ctx.scale(scale, scale);
 		// background gradient
 		var selectionBackgroundGradient = null;
commit f4496b5a886b98b78fba8714debb4b9e26f5009a
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 16:49:47 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    compute nearest zoomlevel with devpixelratio included
    
    and use this for every setZoom call.
    
    Change-Id: I37f0d7503e4087f062576bc03b13bd8155c3c994

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index ba74b2c4c..f8b739a2a 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -380,6 +380,11 @@ L.CanvasTileLayer = L.TileLayer.extend({
 		this._tileHeightPx = this.options.tileSize;
 		this._tilePixelScale = 1;
 
+		// FIXME: workaround for correcting initial zoom with dpiscale included.
+		// The one set during Map constructor is does not include dpiscale because
+		// there we don't have enough info to specialize for calc-canvas
+		map.setZoom(map.getZoom());
+
 		L.TileLayer.prototype.onAdd.call(this, map);
 	},
 
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 6f5677a26..946896e0c 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -452,7 +452,22 @@ L.Map = L.Evented.extend({
 		this._progressBar.end(this);
 	},
 
+	// Compute the nearest zoom level corresponding to the effective zoom-scale (ie, with dpiscale included).
+	findNearestProductZoom: function (zoom) {
+		var clientZoomScale = Math.pow(1.2, (zoom - this.options.zoom));
+
+		var zoomScale = clientZoomScale * L.getCanvasScaleFactor();
+		var nearestZoom = Math.round((Math.log(zoomScale) / Math.log(1.2)) + this.options.zoom);
+		nearestZoom = this._limitZoom(nearestZoom);
+
+		return nearestZoom;
+	},
+
 	setZoom: function (zoom, options) {
+
+		if (this._docLayer instanceof L.CanvasTileLayer)
+			zoom = this.findNearestProductZoom(zoom);
+
 		if (!this._loaded) {
 			this._zoom = this._limitZoom(zoom);
 			return this;
commit e57d49a6421263cb1214d89f90ce0ded23690857
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 15:50:44 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    calc-canvas: make tile size fixed (256) for every device
    
    Change-Id: I4e00b8b43f73f001a8bcfc77931f5fa22982642e

diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 35eae4c14..3daa75e69 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -4,7 +4,8 @@
  */
 
 /* global */
-L.CalcTileLayer = (L.Browser.mobile ? L.TileLayer : L.CanvasTileLayer).extend({
+var BaseTileLayer = L.Browser.mobile ? L.TileLayer : L.CanvasTileLayer;
+L.CalcTileLayer = BaseTileLayer.extend({
 	options: {
 		// TODO: sync these automatically from SAL_LOK_OPTIONS
 		sheetGeometryDataEnabled: true,
@@ -81,7 +82,7 @@ L.CalcTileLayer = (L.Browser.mobile ? L.TileLayer : L.CanvasTileLayer).extend({
 		map.addControl(L.control.tabs());
 		map.addControl(L.control.columnHeader());
 		map.addControl(L.control.rowHeader());
-		L.TileLayer.prototype.onAdd.call(this, map);
+		BaseTileLayer.prototype.onAdd.call(this, map);
 
 		map.on('resize', function () {
 			if (this.isCursorVisible()) {
diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 70f6c8a36..ba74b2c4c 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -373,6 +373,16 @@ L.CanvasTileLayer = L.TileLayer.extend({
 		return false;
 	},
 
+	onAdd: function (map) {
+
+		// Override L.TileLayer._tilePixelScale to 1 (independent of the device).
+		this._tileWidthPx = this.options.tileSize;
+		this._tileHeightPx = this.options.tileSize;
+		this._tilePixelScale = 1;
+
+		L.TileLayer.prototype.onAdd.call(this, map);
+	},
+
 	onRemove: function (map) {
 		this._painter.dispose();
 		L.TileLayer.prototype.onRemove.call(this, map);
commit 7b8dc6411823a0c43312caddc0a0e0b0e89dc2d9
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 15:34:30 2020 +0530
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    use window.devicePixelRatio without rounding
    
    at least for the canvas tile layer.
    
    Change-Id: Ia830cad1fe0aaac6df03288cc1ee9e0371ef6f47

diff --git a/loleaflet/src/core/Util.js b/loleaflet/src/core/Util.js
index 596dfa756..e5f461cab 100644
--- a/loleaflet/src/core/Util.js
+++ b/loleaflet/src/core/Util.js
@@ -159,8 +159,11 @@ L.Util = {
 	// minimal image URI, set to an image when disposing to flush memory
 	emptyImageUrl: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=',
 
-	getDpiScaleFactor: function() {
-		var dpiScale = window.devicePixelRatio ? Math.ceil(window.devicePixelRatio) : 1;
+	getDpiScaleFactor: function(useExactDPR) {
+		var dpiScale = window.devicePixelRatio ? window.devicePixelRatio : 1;
+		if (!useExactDPR)
+			dpiScale = Math.ceil(dpiScale);
+
 		if (dpiScale == 1 && L.Browser.retina) {
 			dpiScale = 2;
 		}
diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index d189ecf6a..70f6c8a36 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -44,7 +44,7 @@ L.CanvasTilePainter = L.Class.extend({
 		this._layer = layer;
 		this._canvas = this._layer._canvas;
 
-		var dpiScale = L.getDpiScaleFactor();
+		var dpiScale = L.getDpiScaleFactor(true /* useExactDPR */);
 		this._dpiScale = dpiScale;
 
 		this._map = this._layer._map;
@@ -214,7 +214,7 @@ L.CanvasTilePainter = L.Class.extend({
 		var part = this._layer._selectedPart;
 		var newSplitPos = splitPanesContext ?
 		    splitPanesContext.getSplitPos(): this._splitPos;
-		var newDpiScale = L.getDpiScaleFactor();
+		var newDpiScale = L.getDpiScaleFactor(true /* useExactDPR */);
 
 		var zoomChanged = (zoom !== this._lastZoom);
 		var partChanged = (part !== this._lastPart);
@@ -242,8 +242,10 @@ L.CanvasTilePainter = L.Class.extend({
 		if (skipUpdate)
 			return;
 
-		if (scaleChanged)
-			this._dpiScale = L.getDpiScaleFactor();
+		if (scaleChanged) {
+			this._dpiScale = L.getDpiScaleFactor(true /* useExactDPR */);
+			console.log('DEBUG: scaleChanged : this._dpiScale = ' + this._dpiScale);
+		}
 
 		if (resizeCanvas || scaleChanged) {
 			this._setCanvasSize(newSize.x, newSize.y);
commit 69157c07b67e28bafc7a0d7d26e6290143c9acc0
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Aug 21 20:43:47 2020 +0100
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    Don't merge - grim hack try to get 1:1 pixels in canvas.
    
    Change-Id: I8ff3f157112295e0c6ef6743de3c878329b98adb

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 9f3b6e02f..d189ecf6a 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -40,22 +40,15 @@ L.CanvasTilePainter = L.Class.extend({
 		debug: true,
 	},
 
-	initialize: function (layer, enableImageSmoothing) {
+	initialize: function (layer) {
 		this._layer = layer;
 		this._canvas = this._layer._canvas;
 
 		var dpiScale = L.getDpiScaleFactor();
-		if (dpiScale === 1 || dpiScale === 2) {
-			enableImageSmoothing = (enableImageSmoothing === true);
-		}
-		else {
-			enableImageSmoothing = (enableImageSmoothing === undefined || enableImageSmoothing);
-		}
-
 		this._dpiScale = dpiScale;
 
 		this._map = this._layer._map;
-		this._setupCanvas(enableImageSmoothing);
+		this._setupCanvas();
 
 		this._topLeft = undefined;
 		this._lastZoom = undefined;
@@ -95,15 +88,11 @@ L.CanvasTilePainter = L.Class.extend({
 		this.stopUpdates();
 	},
 
-	setImageSmoothing: function (enable) {
-		this._canvasCtx.imageSmoothingEnabled = enable;
-		this._canvasCtx.msImageSmoothingEnabled = enable;
-	},
-
-	_setupCanvas: function (enableImageSmoothing) {
+	_setupCanvas: function () {
 		console.assert(this._canvas, 'no canvas element');
 		this._canvasCtx = this._canvas.getContext('2d', { alpha: false });
-		this.setImageSmoothing(enableImageSmoothing);
+		this._canvasCtx.imageSmoothingEnabled = false;
+		this._canvasCtx.msImageSmoothingEnabled = false;
 		var mapSize = this._map.getPixelBounds().getSize();
 		this._lastSize = mapSize;
 		this._lastMapSize = mapSize;
@@ -132,7 +121,7 @@ L.CanvasTilePainter = L.Class.extend({
 
 	clear: function () {
 		this._canvasCtx.save();
-		this._canvasCtx.scale(this._dpiScale, this._dpiScale);
+		this._canvasCtx.scale(1, 1);
 		if (this.options.debug)
 			this._canvasCtx.fillStyle = 'red';
 		else
@@ -177,7 +166,7 @@ L.CanvasTilePainter = L.Class.extend({
 				topLeft.y = ctx.viewBounds.min.y;
 
 			this._canvasCtx.save();
-			this._canvasCtx.scale(this._dpiScale, this._dpiScale);
+			this._canvasCtx.scale(1, 1);
 			this._canvasCtx.translate(-topLeft.x, -topLeft.y);
 
 			// create a clip for the pane/view.
@@ -186,12 +175,11 @@ L.CanvasTilePainter = L.Class.extend({
 			this._canvasCtx.rect(paneBounds.min.x, paneBounds.min.y, paneSize.x + 1, paneSize.y + 1);
 			this._canvasCtx.clip();
 
-			if (this._dpiScale !== 1) {
-				// FIXME: avoid this scaling when possible (dpiScale = 2).
-				this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y, ctx.tileSize.x, ctx.tileSize.y);
-			}
-			else {
-				this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y);
+			this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y);
+			if (this.options.debug)
+			{
+				this._canvasCtx.strokeStyle = 'red';
+				this._canvasCtx.strokeRect(tile.coords.x, tile.coords.y, 256, 256);
 			}
 			this._canvasCtx.restore();
 		}
@@ -204,7 +192,7 @@ L.CanvasTilePainter = L.Class.extend({
 		}
 		var splitPos = splitPanesContext.getSplitPos();
 		this._canvasCtx.save();
-		this._canvasCtx.scale(this._dpiScale, this._dpiScale);
+		this._canvasCtx.scale(1, 1);
 		this._canvasCtx.strokeStyle = 'red';
 		this._canvasCtx.strokeRect(0, 0, splitPos.x, splitPos.y);
 		this._canvasCtx.restore();
@@ -249,6 +237,8 @@ L.CanvasTilePainter = L.Class.extend({
 			!splitPosChanged &&
 			!scaleChanged);
 
+		console.debug('Tile size: ' + this._layer._getTileSize());
+
 		if (skipUpdate)
 			return;
 
@@ -296,8 +286,8 @@ L.CanvasTilePainter = L.Class.extend({
 			for (var j = tileRange.min.y; j <= tileRange.max.y; ++j) {
 				for (var i = tileRange.min.x; i <= tileRange.max.x; ++i) {
 					var coords = new L.TileCoordData(
-						i * ctx.tileSize,
-						j * ctx.tileSize,
+						i * ctx.tileSize.x,
+						j * ctx.tileSize.y,
 						zoom,
 						part);
 
commit 667dec0b2cd6f77a37c55a8c1b841b431cb1a75a
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Aug 21 16:40:29 2020 +0100
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    calc tiles: more debug helpers
    
    Change-Id: I24370b2a35fdfeca360cbaeb296cd2dd3a11e768

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 5829239fa..9f3b6e02f 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -37,7 +37,7 @@ L.TileCoordData.parseKey = function (keyString) {
 L.CanvasTilePainter = L.Class.extend({
 
 	options: {
-		debug: false,
+		debug: true,
 	},
 
 	initialize: function (layer, enableImageSmoothing) {
@@ -133,7 +133,10 @@ L.CanvasTilePainter = L.Class.extend({
 	clear: function () {
 		this._canvasCtx.save();
 		this._canvasCtx.scale(this._dpiScale, this._dpiScale);
-		this._canvasCtx.fillStyle = 'white';
+		if (this.options.debug)
+			this._canvasCtx.fillStyle = 'red';
+		else
+			this._canvasCtx.fillStyle = 'white';
 		this._canvasCtx.fillRect(0, 0, this._width, this._height);
 		this._canvasCtx.restore();
 	},
@@ -277,6 +280,10 @@ L.CanvasTilePainter = L.Class.extend({
 	},
 
 	_paintWholeCanvas: function () {
+
+		if (this.options.debug)
+			this.clear();
+
 		var zoom = this._lastZoom || Math.round(this._map.getZoom());
 		var part = this._lastPart || this._layer._selectedPart;
 
commit c3cea54384d2e2c156f8621ff3a23d577c801b30
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Aug 21 15:54:50 2020 +0100
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    calc tiles: share code for building bounds and panes.
    
    Avoid duplication between tileReady and paint.
    
    Change-Id: Ic3d1c22a1dbeffe1abfffd35ea0d7fbcfd5c1ccc

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 5881803c8..5829239fa 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -63,8 +63,6 @@ L.CanvasTilePainter = L.Class.extend({
 		var splitPanesContext = this._layer.getSplitPanesContext();
 		this._splitPos = splitPanesContext ?
 			splitPanesContext.getSplitPos() : new L.Point(0, 0);
-
-		this._tileSizeCSSPx = undefined;
 		this._updatesRunning = false;
 	},
 
@@ -140,38 +138,40 @@ L.CanvasTilePainter = L.Class.extend({
 		this._canvasCtx.restore();
 	},
 
-	paint: function (tile, viewBounds, paneBoundsList) {
+	// Details of tile areas to render
+	_paintContext: function() {
+		var tileSize = new L.Point(this._layer._getTileSize(), this._layer._getTileSize());
 
-		if (this._tileSizeCSSPx === undefined) {
-			this._tileSizeCSSPx = this._layer._getTileSize();
-		}
+		var viewBounds = this._map.getPixelBounds();
+		var splitPanesContext = this._layer.getSplitPanesContext();
+		var paneBoundsList = splitPanesContext ?
+		    splitPanesContext.getPxBoundList(viewBounds) :
+		    [viewBounds];
+
+		return { tileSize: tileSize,
+			 viewBounds: viewBounds,
+			 paneBoundsList: paneBoundsList };
+	},
+
+	paint: function (tile, ctx) {
+
+		if (!ctx)
+			ctx = this._paintContext();
 
 		var tileTopLeft = tile.coords.getPos();
-		var tileSize = new L.Point(this._tileSizeCSSPx, this._tileSizeCSSPx);
-		var tileBounds = new L.Bounds(tileTopLeft, tileTopLeft.add(tileSize));
+		var tileBounds = new L.Bounds(tileTopLeft, tileTopLeft.add(ctx.tileSize));
 
-		viewBounds = viewBounds || this._map.getPixelBounds();
-		var splitPanesContext = this._layer.getSplitPanesContext();
-		paneBoundsList = paneBoundsList || (
-			splitPanesContext ?
-			splitPanesContext.getPxBoundList(viewBounds) :
-			[viewBounds]
-		);
+		for (var i = 0; i < ctx.paneBoundsList.length; ++i) {
+			var paneBounds = ctx.paneBoundsList[i];
 
-		for (var i = 0; i < paneBoundsList.length; ++i) {
-			var paneBounds = paneBoundsList[i];
-			if (!paneBounds.intersects(tileBounds)) {
+			if (!paneBounds.intersects(tileBounds))
 				continue;
-			}
 
 			var topLeft = paneBounds.getTopLeft();
-			if (topLeft.x) {
-				topLeft.x = viewBounds.min.x;
-			}
-
-			if (topLeft.y) {
-				topLeft.y = viewBounds.min.y;
-			}
+			if (topLeft.x)
+				topLeft.x = ctx.viewBounds.min.x;
+			if (topLeft.y)
+				topLeft.y = ctx.viewBounds.min.y;
 
 			this._canvasCtx.save();
 			this._canvasCtx.scale(this._dpiScale, this._dpiScale);
@@ -185,7 +185,7 @@ L.CanvasTilePainter = L.Class.extend({
 
 			if (this._dpiScale !== 1) {
 				// FIXME: avoid this scaling when possible (dpiScale = 2).
-				this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y, this._tileSizeCSSPx, this._tileSizeCSSPx);
+				this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y, ctx.tileSize.x, ctx.tileSize.y);
 			}
 			else {
 				this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y);
@@ -280,24 +280,17 @@ L.CanvasTilePainter = L.Class.extend({
 		var zoom = this._lastZoom || Math.round(this._map.getZoom());
 		var part = this._lastPart || this._layer._selectedPart;
 
-		var viewSize = new L.Point(this._width, this._height);
-		var viewBounds = new L.Bounds(this._topLeft, this._topLeft.add(viewSize));
-
-		var splitPanesContext = this._layer.getSplitPanesContext();
 		// Calculate all this here intead of doing it per tile.
-		var paneBoundsList = splitPanesContext ?
-			splitPanesContext.getPxBoundList(viewBounds) : [viewBounds];
-		var tileRanges = paneBoundsList.map(this._layer._pxBoundsToTileRange, this._layer);
-
-		var tileSize = this._tileSizeCSSPx || this._layer._getTileSize();
+		var ctx = this._paintContext();
+		var tileRanges = ctx.paneBoundsList.map(this._layer._pxBoundsToTileRange, this._layer);
 
 		for (var rangeIdx = 0; rangeIdx < tileRanges.length; ++rangeIdx) {
 			var tileRange = tileRanges[rangeIdx];
 			for (var j = tileRange.min.y; j <= tileRange.max.y; ++j) {
 				for (var i = tileRange.min.x; i <= tileRange.max.x; ++i) {
 					var coords = new L.TileCoordData(
-						i * tileSize,
-						j * tileSize,
+						i * ctx.tileSize,
+						j * ctx.tileSize,
 						zoom,
 						part);
 
@@ -305,7 +298,7 @@ L.CanvasTilePainter = L.Class.extend({
 					var tile = this._layer._tiles[key];
 					var invalid = tile && tile._invalidCount && tile._invalidCount > 0;
 					if (tile && tile.loaded && !invalid) {
-						this.paint(tile, viewBounds, paneBoundsList);
+						this.paint(tile, ctx);
 					}
 				}
 			}
commit 3b1379dd84d971542b59dee81384e6e8539bf480
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Aug 21 15:47:58 2020 +0100
Commit:     Dennis Francis <dennis.francis at collabora.com>
CommitDate: Tue Aug 25 12:40:51 2020 +0530

    calc tiles: remove partial re-rendering for now.
    
    Drops _shiftAndPaint and _paintRects, blits are fast.
    
    Change-Id: I64779f1037784f4efbe74cdf564b5f09e13b3316

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index f6c29d57a..5881803c8 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -236,7 +236,6 @@ L.CanvasTilePainter = L.Class.extend({
 		var resizeCanvas = !newSize.equals(this._lastSize);
 
 		var topLeftChanged = this._topLeft === undefined || !newTopLeft.equals(this._topLeft);
-
 		var splitPosChanged = !newSplitPos.equals(this._splitPos);
 
 		var skipUpdate = (
@@ -247,9 +246,9 @@ L.CanvasTilePainter = L.Class.extend({
 			!splitPosChanged &&
 			!scaleChanged);
 
-		if (skipUpdate) {
+		if (skipUpdate)
 			return;
-		}
+
 		if (scaleChanged)
 			this._dpiScale = L.getDpiScaleFactor();
 
@@ -261,130 +260,20 @@ L.CanvasTilePainter = L.Class.extend({
 			this.clear();
 		}
 
-		if (mapSizeChanged) {
+		if (mapSizeChanged)
 			this._lastMapSize = newMapSize;
-		}
 
-		if (splitPosChanged) {
+		if (splitPosChanged)
 			this._splitPos = newSplitPos;
-		}
-
-		// TODO: fix _shiftAndPaint for high DPI.
-		var shiftPaintDisabled = true;
-		var fullRepaintNeeded = zoomChanged || partChanged || resizeCanvas ||
-		    shiftPaintDisabled || scaleChanged;
 
 		this._lastZoom = zoom;
 		this._lastPart = part;
 
-		if (fullRepaintNeeded) {
-
-			this._topLeft = newTopLeft;
-			this._paintWholeCanvas();
-
-			if (this.options.debug) {
-				this._drawSplits();
-			}
-
-			return;
-		}
-
-		this._shiftAndPaint(newTopLeft);
-	},
-
-	_shiftAndPaint: function (newTopLeft) {
-
-		console.assert(!this._layer.getSplitPanesContext(), '_shiftAndPaint is broken for split-panes.');
-		var offset = new L.Point(this._width - 1, this._height - 1);
-
-		var dx = newTopLeft.x - this._topLeft.x;
-		var dy = newTopLeft.y - this._topLeft.y;
-		if (!dx && !dy) {
-			return;
-		}
-
-		// Determine the area that needs to be painted as max. two disjoint rectangles.
-		var rectsToPaint = [];
-		this._inMove = true;
-		var oldTopLeft = this._topLeft;
-		var oldBottomRight = oldTopLeft.add(offset);
-		var newBottomRight = newTopLeft.add(offset);
-
-		if (Math.abs(dx) < this._width && Math.abs(dy) < this._height) {
-
-			this._canvasCtx.save();
-			this._canvasCtx.scale(this._dpiScale, this._dpiScale);
-			this._canvasCtx.globalCompositeOperation = 'copy';
-			this._canvasCtx.drawImage(this._canvas, -dx, -dy);
-			this._canvasCtx.globalCompositeOperation = 'source-over';
-			this._canvasCtx.restore();
-
-			var xstart = newTopLeft.x, xend = newBottomRight.x;
-			var ystart = newTopLeft.y, yend = newBottomRight.y;
-			if (dx) {
-				xstart = dx > 0 ? oldBottomRight.x + 1 : newTopLeft.x;
-				xend   = xstart + Math.abs(dx) - 1;
-			}
-
-			if (dy) {
-				ystart = dy > 0 ? oldBottomRight.y + 1 : newTopLeft.y;
-				yend   = ystart + Math.abs(dy) - 1;
-			}
-
-			// rectangle including the x-range that needs painting with full y-range.
-			// This will take care of simultaneous non-zero dx and dy.
-			if (dx) {
-				rectsToPaint.push(new L.Bounds(
-					new L.Point(xstart, newTopLeft.y),
-					new L.Point(xend,   newBottomRight.y)
-				));
-			}
-
-			// rectangle excluding the x-range that needs painting + needed y-range.
-			if (dy) {
-				rectsToPaint.push(new L.Bounds(
-					new L.Point(dx > 0 ? newTopLeft.x : (dx ? xend + 1 : newTopLeft.x), ystart),
-					new L.Point(dx > 0 ? xstart - 1   : newBottomRight.x,               yend)
-				));
-			}
-
-		}
-		else {
-			rectsToPaint.push(new L.Bounds(newTopLeft, newBottomRight));
-		}
-
 		this._topLeft = newTopLeft;
+		this._paintWholeCanvas();
 
-		this._paintRects(rectsToPaint, newTopLeft);
-	},
-
-	_paintRects: function (rects, topLeft) {
-		for (var i = 0; i < rects.length; ++i) {
-			this._paintRect(rects[i], topLeft);
-		}
-	},
-
-	_paintRect: function (rect) {
-		var zoom = this._lastZoom || Math.round(this._map.getZoom());
-		var part = this._lastPart || this._layer._selectedPart;
-		var tileRange = this._layer._pxBoundsToTileRange(rect);
-		var tileSize = this._tileSizeCSSPx || this._layer._getTileSize();
-		for (var j = tileRange.min.y; j <= tileRange.max.y; ++j) {
-			for (var i = tileRange.min.x; i <= tileRange.max.x; ++i) {
-				var coords = new L.TileCoordData(
-					i * tileSize,
-					j * tileSize,
-					zoom,
-					part);
-
-				var key = coords.key();
-				var tile = this._layer._tiles[key];
-				var invalid = tile && tile._invalidCount && tile._invalidCount > 0;
-				if (tile && tile.loaded && !invalid) {
-					this.paint(tile);
-				}
-			}
-		}
+		if (this.options.debug)
+			this._drawSplits();
 	},
 
 	_paintWholeCanvas: function () {


More information about the Libreoffice-commits mailing list