[Libreoffice-commits] online.git: 37 commits - cypress_test/integration_tests loleaflet/css loleaflet/images loleaflet/js loleaflet/src

Tamás Zolnai (via logerrit) logerrit at kemper.freedesktop.org
Thu Sep 17 13:22:38 UTC 2020


 cypress_test/integration_tests/mobile/calc/hamburger_menu_spec.js   |    8 
 cypress_test/integration_tests/mobile/writer/hamburger_menu_spec.js |   16 
 loleaflet/css/leaflet.css                                           |    8 
 loleaflet/css/spreadsheet.css                                       |    2 
 loleaflet/css/toolbar.css                                           |    4 
 loleaflet/images/lc_freezepanes.svg                                 |    1 
 loleaflet/images/lc_freezepanescolumn.svg                           |    1 
 loleaflet/images/lc_freezepanesrow.svg                              |    1 
 loleaflet/js/global.js                                              |    4 
 loleaflet/src/control/Control.ColumnHeader.js                       |   10 
 loleaflet/src/control/Control.Header.js                             |   14 
 loleaflet/src/control/Control.Menubar.js                            |    6 
 loleaflet/src/control/Control.NotebookbarCalc.js                    |   57 +
 loleaflet/src/control/Control.RowHeader.js                          |    8 
 loleaflet/src/core/Util.js                                          |    7 
 loleaflet/src/geometry/Bounds.js                                    |    7 
 loleaflet/src/layer/marker/Marker.Drag.js                           |    6 
 loleaflet/src/layer/marker/Marker.js                                |    7 
 loleaflet/src/layer/tile/CalcTileLayer.js                           |  148 +--
 loleaflet/src/layer/tile/CanvasTileLayer.js                         |  466 +++++-----
 loleaflet/src/layer/tile/GridLayer.js                               |    4 
 loleaflet/src/layer/vector/SplitterLine.js                          |   20 
 loleaflet/src/map/Map.js                                            |   51 -
 loleaflet/src/map/anim/Map.ZoomAnimation.js                         |    3 
 loleaflet/src/unocommands.js                                        |    4 
 25 files changed, 523 insertions(+), 340 deletions(-)

New commits:
commit d29ad2b57f2ae139f246ae8afa81a26fed996a91
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Sep 17 13:28:34 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:54 2020 +0200

    cypress: update tile / marker positions.
    
    It seems the tile container was moved to right with one
    pixel. Update the test accordingly.
    
    Change-Id: Ie8c370419e0b19abaafda379e95f405eea27b64f

diff --git a/cypress_test/integration_tests/mobile/calc/hamburger_menu_spec.js b/cypress_test/integration_tests/mobile/calc/hamburger_menu_spec.js
index 19d49cdab..d57805f04 100644
--- a/cypress_test/integration_tests/mobile/calc/hamburger_menu_spec.js
+++ b/cypress_test/integration_tests/mobile/calc/hamburger_menu_spec.js
@@ -518,7 +518,7 @@ describe('Trigger hamburger menu options.', function() {
 		// Select B2 cell
 		calcHelper.clickOnFirstCell();
 
-		cy.get('.spreadsheet-cell-resize-marker[style=\'transform: translate3d(76px, 11px, 0px); z-index: 11;\']')
+		cy.get('.spreadsheet-cell-resize-marker[style=\'transform: translate3d(77px, 11px, 0px); z-index: 11;\']')
 			.then(function(marker) {
 				expect(marker).to.have.lengthOf(1);
 				var XPos = marker[0].getBoundingClientRect().right + 2;
@@ -565,7 +565,7 @@ describe('Trigger hamburger menu options.', function() {
 		// Select B2 cell
 		calcHelper.clickOnFirstCell();
 
-		cy.get('.spreadsheet-cell-resize-marker[style=\'transform: translate3d(76px, 11px, 0px); z-index: 11;\']')
+		cy.get('.spreadsheet-cell-resize-marker[style=\'transform: translate3d(77px, 11px, 0px); z-index: 11;\']')
 			.then(function(marker) {
 				expect(marker).to.have.lengthOf(1);
 				var XPos = marker[0].getBoundingClientRect().right + 2;
@@ -881,8 +881,8 @@ describe('Trigger hamburger menu options.', function() {
 
 		mobileHelper.selectFromColorPalette(0, 0, 7);
 
-		var firstTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: -1px; top: 5px;\']';
-		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 255px; top: 5px;\']';
+		var firstTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 0px; top: 5px;\']';
+		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 256px; top: 5px;\']';
 		helper.imageShouldBeFullWhiteOrNot(centerTile, true);
 		helper.imageShouldBeFullWhiteOrNot(firstTile, false);
 
diff --git a/cypress_test/integration_tests/mobile/writer/hamburger_menu_spec.js b/cypress_test/integration_tests/mobile/writer/hamburger_menu_spec.js
index 8e46bfb95..7202c06b7 100644
--- a/cypress_test/integration_tests/mobile/writer/hamburger_menu_spec.js
+++ b/cypress_test/integration_tests/mobile/writer/hamburger_menu_spec.js
@@ -703,7 +703,7 @@ describe('Trigger hamburger menu options.', function() {
 	});
 
 	it('Page setup: change paper size.', function() {
-		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 255px; top: 517px;\']';
+		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 256px; top: 517px;\']';
 		helper.imageShouldBeFullWhiteOrNot(centerTile, true);
 
 		openPageWizard();
@@ -725,7 +725,7 @@ describe('Trigger hamburger menu options.', function() {
 	});
 
 	it('Page setup: change paper width.', function() {
-		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 255px; top: 517px;\']';
+		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 256px; top: 517px;\']';
 		helper.imageShouldBeFullWhiteOrNot(centerTile, true);
 
 		openPageWizard();
@@ -748,7 +748,7 @@ describe('Trigger hamburger menu options.', function() {
 	});
 
 	it('Page setup: change paper height.', function() {
-		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 255px; top: 517px;\']';
+		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 256px; top: 517px;\']';
 		helper.imageShouldBeFullWhiteOrNot(centerTile, true);
 
 		openPageWizard();
@@ -771,7 +771,7 @@ describe('Trigger hamburger menu options.', function() {
 	});
 
 	it('Page setup: change orientation.', function() {
-		cy.get('.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 1023px; top: 5px;\']')
+		cy.get('.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 1024px; top: 5px;\']')
 			.should('not.exist');
 
 		// Move the cursor to the right side of the document,
@@ -788,7 +788,7 @@ describe('Trigger hamburger menu options.', function() {
 		helper.clickOnIdle('.ui-combobox-text', 'Landscape');
 
 		// We got some extra tiles horizontally.
-		cy.get('.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 1023px; top: 5px;\']')
+		cy.get('.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 1024px; top: 5px;\']')
 			.should('exist');
 
 		// Check that the page wizard shows the right value after reopen.
@@ -801,7 +801,7 @@ describe('Trigger hamburger menu options.', function() {
 	});
 
 	it('Page setup: change margin.', function() {
-		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 255px; top: 261px;\']';
+		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 256px; top: 261px;\']';
 		helper.imageShouldBeFullWhiteOrNot(centerTile, false);
 
 		openPageWizard();
@@ -826,7 +826,7 @@ describe('Trigger hamburger menu options.', function() {
 		// Hide text so the center tile is full white.
 		hideText();
 
-		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 255px; top: 261px;\']';
+		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 256px; top: 261px;\']';
 		helper.imageShouldBeFullWhiteOrNot(centerTile, true);
 
 		// Enable it first -> spaces will be visible.
@@ -856,7 +856,7 @@ describe('Trigger hamburger menu options.', function() {
 		// Hide text so the center tile is full white.
 		hideText();
 
-		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 255px; top: 261px;\']';
+		var centerTile = '.leaflet-tile-loaded[style=\'width: 256px; height: 256px; left: 256px; top: 261px;\']';
 		helper.imageShouldBeFullWhiteOrNot(centerTile, true);
 
 		// Enable it first.
commit 49cdd8cafd87cc36017fb3407d49b52dadc43dad
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Tue Sep 15 22:04:52 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:54 2020 +0200

    split panes: Don't expose the freeze panes buttons in the toolbar.
    
    The split panes are not modified that often, no need to have buttons to
    set that up in the toolbar.
    
    Change-Id: I9c7920f6dd57de5f507450e15fcde615ad941f1c

diff --git a/loleaflet/src/control/Control.TopToolbar.js b/loleaflet/src/control/Control.TopToolbar.js
index 027131dbc..29cf538d4 100644
--- a/loleaflet/src/control/Control.TopToolbar.js
+++ b/loleaflet/src/control/Control.TopToolbar.js
@@ -217,10 +217,6 @@ L.Control.TopToolbar = L.Control.extend({
 			{type: 'drop',  id: 'insertshapes',  img: 'basicshapes_ellipse', hint: _('Insert shapes'), overlay: {onShow: window.insertShapes}, html: window.getShapesPopupHtml()},
 			{type: 'button',  id: 'link',  img: 'link', hint: _UNO('.uno:HyperlinkDialog', '', true), disabled: true},
 			{type: 'button',  id: 'insertsymbol', img: 'insertsymbol', hint: _UNO('.uno:InsertSymbol', '', true), uno: 'InsertSymbol'},
-			{type: 'break', id: 'breakobject', hidden: true},
-			{type: 'button', id: 'freezepanes',  img: 'freezepanes', hint: _UNO('.uno:FreezePanes', 'spreadsheet', true), hidden: true, uno:'FreezePanes'},
-			{type: 'button', id: 'freezepanescolumn',img: 'freezepanescolumn', hint: _UNO('.uno:FreezePanesColumn', 'spreadsheet', true), uno: 'FreezePanesColumn'},
-			{type: 'button', id: 'freezepanesrow', img: 'freezepanesrow', hint: _UNO('.uno:FreezePanesRow', 'spreadsheet', true), uno: 'FreezePanesRow'},
 			{type: 'spacer'},
 			{type: 'button',  id: 'edit',  img: 'edit'},
 			{type: 'button',  id: 'sidebar', img: 'sidebar_modify_page', hint: _UNO('.uno:Sidebar', '', true), uno: '.uno:Sidebar', hidden: true},
@@ -279,7 +275,7 @@ L.Control.TopToolbar = L.Control.extend({
 		case 'spreadsheet':
 			if (toolbarUp) {
 				toolbarUp.show('textalign', 'wraptext', 'breakspacing', 'insertannotation', 'conditionalformaticonset',
-				'numberformatcurrency', 'numberformatpercent', 'breakobject', 'freezepanes',
+				'numberformatcurrency', 'numberformatpercent',
 				'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'togglemergecells', 'breakmergecells',
 				'setborderstyle', 'sortascending', 'sortdescending', 'breaksorting', 'backgroundcolor', 'breaksidebar', 'sidebar');
 				toolbarUp.remove('styles');
commit fb0deb2a13c00f8792370b309b68bf0343246231
Author:     Pranam Lashkari <lpranam at collabora.com>
AuthorDate: Fri Aug 21 07:44:11 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:54 2020 +0200

    leaflet: added freeze pan buttons to view menu
    
    Change-Id: I9ba7a0982b15d097e21d93a6e18289455f0f8139

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index be8312573..e53958f14 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -404,6 +404,12 @@ L.Control.Menubar = L.Control.extend({
 			{name: _UNO('.uno:ViewMenu', 'spreadsheet'), id: 'view', type: 'menu', menu: [
 				{name: _UNO('.uno:FullScreen', 'spreadsheet'), id: 'fullscreen', type: 'action'},
 				{type: 'separator'},
+				{name: _UNO('.uno:FreezePanes', 'spreadsheet', true), id: 'FreezePanes', type: 'action', uno: '.uno:FreezePanes'},
+				{name: _UNO('.uno:FreezeCellsMenu', 'spreadsheet', true), id: 'FreezeCellsMenu', type: 'menu', uno: '.uno:FreezeCellsMenu', menu: [
+					{name: _UNO('.uno:FreezePanesColumn', 'spreadsheet', true), id: 'FreezePanesColumn', type: 'action', uno: '.uno:FreezePanesColumn'},
+					{name: _UNO('.uno:FreezePanesRow', 'spreadsheet', true), id: 'FreezePanesRow', type: 'action', uno: '.uno:FreezePanesRow'}
+				]},
+				{type: 'separator'},
 				{uno: '.uno:Sidebar'},
 			]},
 			{name: _UNO('.uno:InsertMenu', 'spreadsheet'), id: 'insert', type: 'menu', menu: [
diff --git a/loleaflet/src/unocommands.js b/loleaflet/src/unocommands.js
index 1c28a39d4..cfbd2d114 100644
--- a/loleaflet/src/unocommands.js
+++ b/loleaflet/src/unocommands.js
@@ -122,6 +122,7 @@ var unoCommandsArray = {
 	FormatXErrorBars:{global:{menu:_('Format X Error Bars...'),},},
 	FormatYErrorBars:{global:{menu:_('Format Y Error Bars...'),},},
 	FormattingMarkMenu:{global:{menu:_('Formatting Mark'),},},
+	FreezeCellsMenu:{spreadsheet:{menu:_('Freeze ~Cells'),},},
 	FreezePanes:{spreadsheet:{menu:_('Freeze ~Rows and Columns'),},},
 	FreezePanesColumn:{spreadsheet:{menu:_('Freeze First Column'),},},
 	FreezePanesRow:{spreadsheet:{menu:_('Freeze First Row'),},},
commit 4eab08e62b506e69ce30b850b105a8246419fd54
Author:     Pranam Lashkari <lpranam at collabora.com>
AuthorDate: Thu Aug 20 03:47:07 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:54 2020 +0200

    leaflet: added freeze pan buttons to toolbar
    
    Change-Id: Ifb9ae58deef77397a5d5eb7c0bfd85625f1a4e74

diff --git a/loleaflet/css/toolbar.css b/loleaflet/css/toolbar.css
index a994cd4b2..5a0012c0e 100644
--- a/loleaflet/css/toolbar.css
+++ b/loleaflet/css/toolbar.css
@@ -763,6 +763,10 @@ button.leaflet-control-search-next
 .w2ui-icon.fullscreen-presentation{ background: url('images/lc_fullscreen-presentation-toolbar-mobile.svg') no-repeat center !important;}
 .w2ui-icon.insertion_mobile_wizard{ background: url('images/lc_insertion_mobile_wizard.svg') no-repeat center !important; }
 .w2ui-icon.insertcomment{ background: url('images/lc_insertcomment.svg') no-repeat center !important; }
+.w2ui-icon.freezepanes{ background: url('images/lc_freezepanes.svg') no-repeat center !important; }
+.w2ui-icon.freezepanescolumn{ background: url('images/lc_freezepanescolumn.svg') no-repeat center !important; }
+.w2ui-icon.freezepanesrow{ background: url('images/lc_freezepanesrow.svg') no-repeat center !important; }
+
 
 .w2ui-icon.vereign{ background: url('images/vereign.png') no-repeat center !important; }
 
diff --git a/loleaflet/src/control/Control.TopToolbar.js b/loleaflet/src/control/Control.TopToolbar.js
index 29cf538d4..027131dbc 100644
--- a/loleaflet/src/control/Control.TopToolbar.js
+++ b/loleaflet/src/control/Control.TopToolbar.js
@@ -217,6 +217,10 @@ L.Control.TopToolbar = L.Control.extend({
 			{type: 'drop',  id: 'insertshapes',  img: 'basicshapes_ellipse', hint: _('Insert shapes'), overlay: {onShow: window.insertShapes}, html: window.getShapesPopupHtml()},
 			{type: 'button',  id: 'link',  img: 'link', hint: _UNO('.uno:HyperlinkDialog', '', true), disabled: true},
 			{type: 'button',  id: 'insertsymbol', img: 'insertsymbol', hint: _UNO('.uno:InsertSymbol', '', true), uno: 'InsertSymbol'},
+			{type: 'break', id: 'breakobject', hidden: true},
+			{type: 'button', id: 'freezepanes',  img: 'freezepanes', hint: _UNO('.uno:FreezePanes', 'spreadsheet', true), hidden: true, uno:'FreezePanes'},
+			{type: 'button', id: 'freezepanescolumn',img: 'freezepanescolumn', hint: _UNO('.uno:FreezePanesColumn', 'spreadsheet', true), uno: 'FreezePanesColumn'},
+			{type: 'button', id: 'freezepanesrow', img: 'freezepanesrow', hint: _UNO('.uno:FreezePanesRow', 'spreadsheet', true), uno: 'FreezePanesRow'},
 			{type: 'spacer'},
 			{type: 'button',  id: 'edit',  img: 'edit'},
 			{type: 'button',  id: 'sidebar', img: 'sidebar_modify_page', hint: _UNO('.uno:Sidebar', '', true), uno: '.uno:Sidebar', hidden: true},
@@ -275,7 +279,7 @@ L.Control.TopToolbar = L.Control.extend({
 		case 'spreadsheet':
 			if (toolbarUp) {
 				toolbarUp.show('textalign', 'wraptext', 'breakspacing', 'insertannotation', 'conditionalformaticonset',
-				'numberformatcurrency', 'numberformatpercent',
+				'numberformatcurrency', 'numberformatpercent', 'breakobject', 'freezepanes',
 				'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'togglemergecells', 'breakmergecells',
 				'setborderstyle', 'sortascending', 'sortdescending', 'breaksorting', 'backgroundcolor', 'breaksidebar', 'sidebar');
 				toolbarUp.remove('styles');
commit b7e5604bc300d9325c309f83965929117862e3de
Author:     Pranam Lashkari <lpranam at collabora.com>
AuthorDate: Thu Aug 20 03:46:39 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:54 2020 +0200

    notebookbar: added freeze pan buttons in calc
    
    added icons too
    
    Change-Id: I913f315c2e5bfcfbf6f82677ecffe76eaf86ea2a

diff --git a/loleaflet/images/lc_freezepanes.svg b/loleaflet/images/lc_freezepanes.svg
new file mode 100644
index 000000000..4db353960
--- /dev/null
+++ b/loleaflet/images/lc_freezepanes.svg
@@ -0,0 +1 @@
+<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 3v16h18v-16zm6 4h6c.554 0 1 .446 1 1v3c0 .554-.446 1-1 1h-6c-.554 0-1-.446-1-1v-3c0-.554.446-1 1-1z" fill="#fff"/><path d="m2 3v1 15c0 .554.446 1 1 1h18c.554 0 1-.446 1-1v-15-1h-1-5-1-6-1-5zm1 1h5v3h-5zm6 0h6v3c.554 0 1 .446 1 1h5v3h-5c0 .554-.446 1-1 1v3h-6v-3c-.554 0-1-.446-1-1h-5v-3h5c0-.554.446-1 1-1zm7 0h5v3h-5zm-13 8h5v3h-5zm13 0h5v3h-5zm-13 4h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5z" fill="#808080"/><g fill="#eac282"><g fill-rule="evenodd"><path d="m7.0253906 4-4.0253906 2.4160156v.5839844h.9746094l4.0253906-2.4160156v-.5839844z"/><path d="m7.0253906 8-4.0253906 2.416016v.583984h.9746094l4.0253906-2.416016v-.583984z"/><path d="m7.0253906 12-4.0253906 2.416016v.583984h.9746094l4.0253906-2.416016v-.583984z"/><path d="m7.0253906 16-4.0253906 2.416016v.583984h.9746094l4.0253906-2.416016v-.583984z"/><path d="m13.882812 4-4.882812 2.4414062v.5585938h1.117188l4.882812-2.4414062v-.5585938z"/><path d="m20.02539 4-4.02539 2
 .4160156v.5839844h.97461l4.02539-2.4160156v-.5839844z"/></g><path d="m2 3h20v1h-20z"/><path d="m2 7v1h6c0-.554.446-1 1-1zm13 0c.554 0 1 .446 1 1h6v-1z"/><path d="m2 3h1v16h-1z"/><path d="m8 4v4c0-.554.446-1 1-1v-3zm0 7v9h1v-8c-.554 0-1-.446-1-1z"/><path d="m15 4v3h1v-3z"/><path d="m21 4h1v3h-1z"/><path d="m3 15h5v1h-5z"/><path d="m3 11h5v1h-5z"/><path d="m3 19h5v1h-5z"/><path d="m2 19a1 1 0 0 0 1 1v-1z"/></g><path d="m9 8h6v3h-6z" fill="#4d82b8"/></svg>
\ No newline at end of file
diff --git a/loleaflet/images/lc_freezepanescolumn.svg b/loleaflet/images/lc_freezepanescolumn.svg
new file mode 100644
index 000000000..417f4bf32
--- /dev/null
+++ b/loleaflet/images/lc_freezepanescolumn.svg
@@ -0,0 +1 @@
+<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 4v15h5v-15zm7 0v15h11v-15z" fill="#fff"/><path d="m10 3v1h5v3h-5v1h5v3h-5v1h5v3h-5v1h5v3h-5v1h11c.554 0 1-.446 1-1v-15c0-.554-.446-1-1-1zm6 1h5v3h-5zm0 4h5v3h-5zm0 4h5v3h-5zm0 4h5v3h-5z" fill="#808080"/><path d="m3 3c-.554 0-1 .446-1 1v15c0 .554.446 1 1 1h5 1v-1-15-1h-1zm0 1h4.0253906l-4.0253906 2.4160156zm5 .5839844v2.4160156h-4.0253906zm-5 3.4160156h4.0253906l-4.0253906 2.416016zm5 .5839844v2.4160156h-4.0253906zm-5 3.4160156h4.0253906l-4.0253906 2.416016zm5 .583984v2.416016h-4.0253906zm-5 3.416016h4.0253906l-4.0253906 2.416016zm5 .583984v2.416016h-4.0253906z" fill="#eac282"/></svg>
\ No newline at end of file
diff --git a/loleaflet/images/lc_freezepanesrow.svg b/loleaflet/images/lc_freezepanesrow.svg
new file mode 100644
index 000000000..78ce359e1
--- /dev/null
+++ b/loleaflet/images/lc_freezepanesrow.svg
@@ -0,0 +1 @@
+<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m3 4v4h18v-4zm0 5v10h18v-10z" fill="#fff"/><path d="m2 9v10c0 .554.446 1 1 1h18c.554 0 1-.446 1-1v-10h-1v2h-5v-2h-1v2h-6v-2h-1v2h-5v-2zm1 3h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5zm-13 4h5v3h-5zm6 0h6v3h-6zm7 0h5v3h-5z" fill="#808080"/><path d="m3 3c-.554 0-1 .446-1 1v3 1h1 18 1v-1-3c0-.554-.446-1-1-1zm0 1h4.0253906l-4.0253906 2.4160156zm6 0h4.882812l-4.882812 2.4414062zm7 0h4.025391l-4.025391 2.4160156zm-1 .5585938v2.4414062h-4.882812zm-7 .0253906v2.4160156h-4.0253906zm13 0v2.4160156h-4.025391z" fill="#eac282"/></svg>
\ No newline at end of file
diff --git a/loleaflet/src/control/Control.NotebookbarCalc.js b/loleaflet/src/control/Control.NotebookbarCalc.js
index f21959f7b..6fe096450 100644
--- a/loleaflet/src/control/Control.NotebookbarCalc.js
+++ b/loleaflet/src/control/Control.NotebookbarCalc.js
@@ -2060,6 +2060,63 @@ L.Control.NotebookbarCalc = L.Control.NotebookbarWriter.extend({
 																						}
 																					]
 																				},
+																				{
+																					'id': 'freeze-section1',
+																					'type': 'container',
+																					'text': '',
+																					'enabled': 'true',
+																					'vertical': 'true',
+																					'children': [
+																						{
+																							'id': 'Section7',
+																							'type': 'toolbox',
+																							'text': '',
+																							'enabled': 'true',
+																							'children': [
+																								{
+																									'type': 'toolitem',
+																									'text': _UNO('.uno:FreezePanes', 'spreadsheet', true),
+																									'command': '.uno:FreezePanes'
+																								}
+																							]
+																						}
+																					]
+																				},
+																				{
+																					'id': 'freeze-section2',
+																					'type': 'container',
+																					'text': '',
+																					'enabled': 'true',
+																					'vertical': 'true',
+																					'children': [
+																						{
+																							'id': 'Section7',
+																							'type': 'toolbox',
+																							'text': '',
+																							'enabled': 'true',
+																							'children': [
+																								{
+																									'type': 'toolitem',
+																									'text':_UNO('.uno:FreezePanesColumn', 'spreadsheet', true),
+																									'command': '.uno:FreezePanesColumn'
+																								}
+																							]
+																						},
+																						{
+																							'id': 'Section10',
+																							'type': 'toolbox',
+																							'text': '',
+																							'enabled': 'true',
+																							'children': [
+																								{
+																									'type': 'toolitem',
+																									'text': _UNO('.uno:FreezePanesRow', 'spreadsheet', true),
+																									'command': '.uno:FreezePanesRow'
+																								}
+																							]
+																						}
+																					]
+																				}
 																			]
 																		}
 																	]
diff --git a/loleaflet/src/unocommands.js b/loleaflet/src/unocommands.js
index 655424700..1c28a39d4 100644
--- a/loleaflet/src/unocommands.js
+++ b/loleaflet/src/unocommands.js
@@ -122,6 +122,9 @@ var unoCommandsArray = {
 	FormatXErrorBars:{global:{menu:_('Format X Error Bars...'),},},
 	FormatYErrorBars:{global:{menu:_('Format Y Error Bars...'),},},
 	FormattingMarkMenu:{global:{menu:_('Formatting Mark'),},},
+	FreezePanes:{spreadsheet:{menu:_('Freeze ~Rows and Columns'),},},
+	FreezePanesColumn:{spreadsheet:{menu:_('Freeze First Column'),},},
+	FreezePanesRow:{spreadsheet:{menu:_('Freeze First Row'),},},
 	FullScreen:{global:{menu:_('F~ull Screen'),},},
 	GoalSeekDialog:{spreadsheet:{menu:_('~Goal Seek...'),},},
 	Group:{global:{menu:_('~Group...'),},},
commit ed0c1e34770c2dd4b346880f6e951851f1c171bf
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Tue Sep 15 21:36:14 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:51 2020 +0200

    split panes: No dragging of the split lines currently.
    
    It is too buggy, let's instead allow only setting of that via the menu,
    similarly to what the desktop LO does.
    
    Change-Id: I219b2535e0cbd5310fe2a3a9ebf2098536d5c175

diff --git a/loleaflet/css/leaflet.css b/loleaflet/css/leaflet.css
index d8d8bd651..573815780 100644
--- a/loleaflet/css/leaflet.css
+++ b/loleaflet/css/leaflet.css
@@ -984,7 +984,9 @@ input.clipboard {
 }
 
 .leaflet-pane-splitter {
-	cursor: grab;
+	/* FIXME when we are able to drag it again:
+	cursor: grab; */
+	cursor: default;
 	stroke: #e0e0e0;
 	fill: #e0e0e0;
 	opacity: 1;
@@ -996,11 +998,13 @@ input.clipboard {
 	fill: #eeeeee;
 }
 
+/* FIXME when we are able to drag it again:
 path.leaflet-pane-splitter:hover {
 	opacity: 1 !important;
 	stroke: #cdcdcd;
 	fill: #cdcdcd;
 }
+*/
 
 .input-help {
 	border-radius: 15px;
@@ -1022,4 +1026,4 @@ path.leaflet-pane-splitter:hover {
 	display: block;
 	text-indent: 20px;
 	text-align: justify;
-}
\ No newline at end of file
+}
diff --git a/loleaflet/src/layer/vector/SplitterLine.js b/loleaflet/src/layer/vector/SplitterLine.js
index 9a8d25523..b52b3dcdf 100644
--- a/loleaflet/src/layer/vector/SplitterLine.js
+++ b/loleaflet/src/layer/vector/SplitterLine.js
@@ -68,6 +68,7 @@ L.SplitterLine = L.Rectangle.extend({
 
 		L.Rectangle.prototype.onAdd.call(this);
 
+		/* FIXME No dragging currently, it still needs a lot of polishing.
 		if (!this.dragging) {
 			this.makeDraggable();
 		}
@@ -76,6 +77,7 @@ L.SplitterLine = L.Rectangle.extend({
 			var node = nodeData.getNode();
 			L.DomEvent.on(node, 'mousedown', this._onDragStart, this);
 		}.bind(this));
+		*/
 
 		this.addClass('leaflet-pane-splitter');
 
commit f0b63eb7654d78b47958e300613591d016485f21
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Tue Sep 15 21:33:14 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    split panes: No split lines at all when they are at 0 position.
    
    Change-Id: I9fee28f32acdabd4768b095a471f26e5e8e9a378

diff --git a/loleaflet/src/layer/vector/SplitterLine.js b/loleaflet/src/layer/vector/SplitterLine.js
index c8ad0409c..9a8d25523 100644
--- a/loleaflet/src/layer/vector/SplitterLine.js
+++ b/loleaflet/src/layer/vector/SplitterLine.js
@@ -2,7 +2,7 @@
 /*
  * L.SplitterLine is a draggable L.Rectangle to be used as control for split-panes.
  */
-/* global $ */
+
 L.SplitterLine = L.Rectangle.extend({
 
 	options: {
@@ -43,14 +43,20 @@ L.SplitterLine = L.Rectangle.extend({
 		var xmin = isHoriz ? splitPos.x - thickness/2 : -size.x;
 		var xmax = isHoriz ? splitPos.x + thickness/2 : size.x;
 
-		if (!this._dragStarted && splitPos.y == 0 && !isHoriz)
-			xmax = thickness/2;
+		// No split line when it is at the zero position
+		if (!this._dragStarted && splitPos.y == 0 && !isHoriz) {
+			xmin = 0;
+			xmax = 0;
+		}
 
 		var ymin = !isHoriz ? splitPos.y - thickness/2 : -size.y;
 		var ymax = !isHoriz ? splitPos.y + thickness/2 : size.y;
 
-		if (!this._dragStarted && splitPos.x == 0 && isHoriz)
-			ymax = thickness/2;
+		// No split line when it is at the zero position
+		if (!this._dragStarted && splitPos.x == 0 && isHoriz) {
+			ymin = 0;
+			ymax = 0;
+		}
 
 		return new L.LatLngBounds(
 			map.unproject(new L.Point(xmin, ymin)),
@@ -72,7 +78,6 @@ L.SplitterLine = L.Rectangle.extend({
 		}.bind(this));
 
 		this.addClass('leaflet-pane-splitter');
-		$('.leaflet-pane-splitter').parent().css('overflow', 'visible');
 
 		this._map.on('zoomlevelschange', this.update, this);
 	},
commit f668b590010f4487a1dd1f7171131334fb98d908
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Tue Sep 15 09:15:44 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: More reliable check for the desktop / mobile / tablet.
    
    Change-Id: I7b1ea581051608e020fd6e4615be9bc9b919c01f

diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js
index 0b39b8d21..aeb62042b 100644
--- a/loleaflet/js/global.js
+++ b/loleaflet/js/global.js
@@ -189,6 +189,10 @@
 
 			return !L.Browser.mobile;
 		},
+		useCanvasLayer: function() {
+			// FIXME the CanvasTileLayer is so far desktop-only
+			return global.mode.isDesktop();
+		},
 		getDeviceFormFactor: function() {
 			if (window.mode.isMobile())
 				return 'mobile';
diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index eedf8966a..e6813ad65 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -4,7 +4,9 @@
  */
 
 /* global */
-var BaseTileLayer = L.Browser.mobile ? L.TileLayer : L.CanvasTileLayer;
+
+var BaseTileLayer = window.mode.useCanvasLayer() ? L.CanvasTileLayer : L.TileLayer;
+
 L.CalcTileLayer = BaseTileLayer.extend({
 	options: {
 		// TODO: sync these automatically from SAL_LOK_OPTIONS
diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 0790a24c7..5c93af7de 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -396,6 +396,8 @@ L.CanvasTileLayer = L.TileLayer.extend({
 	},
 
 	onAdd: function (map) {
+		if (!window.mode.useCanvasLayer())
+			return;
 
 		// Override L.TileLayer._tilePixelScale to 1 (independent of the device).
 		this._tileWidthPx = this.options.tileSize;
diff --git a/loleaflet/src/map/anim/Map.ZoomAnimation.js b/loleaflet/src/map/anim/Map.ZoomAnimation.js
index ddd38486f..25738c638 100644
--- a/loleaflet/src/map/anim/Map.ZoomAnimation.js
+++ b/loleaflet/src/map/anim/Map.ZoomAnimation.js
@@ -8,7 +8,8 @@ L.Map.mergeOptions({
 	zoomAnimationThreshold: 4
 });
 
-var zoomAnimated = L.DomUtil.TRANSITION && L.Browser.any3d && !L.Browser.mobileOpera;
+// Conditions for the animated zoom
+var zoomAnimated = L.DomUtil.TRANSITION && L.Browser.any3d && !L.Browser.mobileOpera && !window.mode.useCanvasLayer();
 
 if (zoomAnimated) {
 
commit 0176bbeb6a2dab57b04eeaac2b0e65448a2845cc
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Thu Sep 10 15:35:27 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: get the right core px size of the canvas across.
    
    Change-Id: Ib079097b9d5caf707bd95b286d675791b5df9255

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 91be11179..0790a24c7 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -97,16 +97,16 @@ L.CanvasTilePainter = L.Class.extend({
 	},
 
 	_setCanvasSize: function (widthCSSPx, heightCSSPx) {
-		var pixWidth = Math.floor(widthCSSPx * this._dpiScale);
-		var pixHeight = Math.floor(heightCSSPx * this._dpiScale);
+		this._pixWidth = Math.floor(widthCSSPx * this._dpiScale);
+		this._pixHeight = Math.floor(heightCSSPx * this._dpiScale);
 
 		// real pixels have to be integral
-		this._canvas.width = pixWidth;
-		this._canvas.height = pixHeight;
+		this._canvas.width = this._pixWidth;
+		this._canvas.height = this._pixHeight;
 
 		// CSS pixels can be fractional, but need to round to the same real pixels
-		var cssWidth = pixWidth / this._dpiScale; // NB. beware
-		var cssHeight = pixHeight / this._dpiScale;
+		var cssWidth = this._pixWidth / this._dpiScale; // NB. beware
+		var cssHeight = this._pixHeight / this._dpiScale;
 		this._canvas.style.width = cssWidth.toFixed(4) + 'px';
 		this._canvas.style.height = cssHeight.toFixed(4) + 'px';
 
@@ -146,8 +146,10 @@ L.CanvasTilePainter = L.Class.extend({
 		var paneBoundsList = splitPanesContext ?
 		    splitPanesContext.getPxBoundList(viewBounds) :
 		    [viewBounds];
+		var canvasCorePx = new L.Point(this._pixWidth, this._pixHeight);
 
-		return { tileSize: tileSize,
+		return { canvasSize: canvasCorePx,
+			 tileSize: tileSize,
 			 viewBounds: viewBounds,
 			 paneBoundsList: paneBoundsList };
 	},
commit f9cfed47d48a4aa7cb2b93f159871830ddef0add
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Thu Sep 10 12:47:42 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    Adjust splitline thickness according to zoom level
    
    Change-Id: I33c398f1545860fb2f77d9d8dcdd8f632c2603ca

diff --git a/loleaflet/src/layer/vector/SplitterLine.js b/loleaflet/src/layer/vector/SplitterLine.js
index 547663fe7..c8ad0409c 100644
--- a/loleaflet/src/layer/vector/SplitterLine.js
+++ b/loleaflet/src/layer/vector/SplitterLine.js
@@ -38,7 +38,7 @@ L.SplitterLine = L.Rectangle.extend({
 
 		this._lastPos = isHoriz ? splitPos.x : splitPos.y;
 
-		var thickness = 4;
+		var thickness = 4 * 10 / map._zoom;
 
 		var xmin = isHoriz ? splitPos.x - thickness/2 : -size.x;
 		var xmax = isHoriz ? splitPos.x + thickness/2 : size.x;
@@ -73,6 +73,8 @@ L.SplitterLine = L.Rectangle.extend({
 
 		this.addClass('leaflet-pane-splitter');
 		$('.leaflet-pane-splitter').parent().css('overflow', 'visible');
+
+		this._map.on('zoomlevelschange', this.update, this);
 	},
 
 	_onDragStart: function(evt) {
commit 284e8ce308f2e8a3ea124f93fb7f8c27fbed0910
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Wed Sep 9 15:08:20 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    Don't block handling of touch events
    
    This is partial revert of 901ecca313.
    Handles (Markers) 'down' handler disabled
    main TouchGesture handler what caused
    taps to be ignored. Eg. double click didn't
    enter edit mode for a Calc cell.
    
    Change-Id: Id7097e9ad513e56a71423a6d6a8ac5105c373f77

diff --git a/loleaflet/src/layer/marker/Marker.Drag.js b/loleaflet/src/layer/marker/Marker.Drag.js
index 179408e9b..1df958e52 100644
--- a/loleaflet/src/layer/marker/Marker.Drag.js
+++ b/loleaflet/src/layer/marker/Marker.Drag.js
@@ -16,7 +16,6 @@ L.Handler.MarkerDrag = L.Handler.extend({
 		}
 
 		this._draggable.on({
-			down: this._onDown,
 			dragstart: this._onDragStart,
 			drag: this._onDrag,
 			dragend: this._onDragEnd,
@@ -28,7 +27,6 @@ L.Handler.MarkerDrag = L.Handler.extend({
 
 	removeHooks: function () {
 		this._draggable.off({
-			down: this._onDown,
 			dragstart: this._onDragStart,
 			drag: this._onDrag,
 			dragend: this._onDragEnd,
@@ -54,10 +52,6 @@ L.Handler.MarkerDrag = L.Handler.extend({
 			this._draggable.freezeY(boolChoice);
 	},
 
-	_onDown: function (e) {
-		this._marker.fire('down', e);
-	},
-
 	_onDragStart: function (e) {
 		this._marker
 		    .closePopup()
diff --git a/loleaflet/src/layer/marker/Marker.js b/loleaflet/src/layer/marker/Marker.js
index a73c1826d..10e8038ad 100644
--- a/loleaflet/src/layer/marker/Marker.js
+++ b/loleaflet/src/layer/marker/Marker.js
@@ -23,7 +23,6 @@ L.Marker = L.Layer.extend({
 	initialize: function (latlng, options) {
 		L.setOptions(this, options);
 		this._latlng = L.latLng(latlng);
-		this.on('down', this.onDown);
 	},
 
 	setDraggable: function(val) {
@@ -55,12 +54,6 @@ L.Marker = L.Layer.extend({
 		this._removeShadow();
 	},
 
-	onDown: function () {
-		if (this._map && this._map.touchGesture) {
-			this._map.touchGesture.disable();
-		}
-	},
-
 	getEvents: function () {
 		var events = {viewreset: this.update};
 
commit 26e87932aee04b2bf23e4af9dc53755ac0e27c02
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Wed Sep 9 12:02:50 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc tiles: clarify some magic.
    
    Change-Id: I2d95dd09b5640a5216e72366493ddf77541c8b73

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 2b8eb00db..91be11179 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -161,7 +161,9 @@ L.CanvasTilePainter = L.Class.extend({
 		var tileBounds = new L.Bounds(tileTopLeft, tileTopLeft.add(ctx.tileSize));
 
 		for (var i = 0; i < ctx.paneBoundsList.length; ++i) {
+			// co-ordinates of this pane in core document pixels
 			var paneBounds = this._layer._cssBoundsToCore(ctx.paneBoundsList[i]);
+			// co-ordinates of the main-(bottom right) pane in core document pixels
 			var viewBounds = this._layer._cssBoundsToCore(ctx.viewBounds);
 
 			// into real pixel-land ...
@@ -171,9 +173,10 @@ L.CanvasTilePainter = L.Class.extend({
 			if (!paneBounds.intersects(tileBounds))
 				continue;
 
-			var offset = paneBounds.getTopLeft(); // allocates
-			offset.x = Math.min(offset.x, viewBounds.min.x);
-			offset.y = Math.min(offset.y, viewBounds.min.y);
+			var paneOffset = paneBounds.getTopLeft(); // allocates
+			// Cute way to detect the in-canvas pixel offset of each pane
+			paneOffset.x = Math.min(paneOffset.x, viewBounds.min.x);
+			paneOffset.y = Math.min(paneOffset.y, viewBounds.min.y);
 
 			// intersect - to avoid state thrash through clipping
 			var crop = new L.Bounds(tileBounds.min, tileBounds.max);
@@ -189,8 +192,8 @@ L.CanvasTilePainter = L.Class.extend({
 						  crop.min.x - tileBounds.min.x,
 						  crop.min.y - tileBounds.min.y,
 						  cropWidth, cropHeight,
-						  crop.min.x - offset.x,
-						  crop.min.y - offset.y,
+						  crop.min.x - paneOffset.x,
+						  crop.min.y - paneOffset.y,
 						  cropWidth, cropHeight);
 			if (this._layer._debug)
 			{
commit d1971d3a7ddd1973c415b9cbe202f39a0b39faee
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Sep 8 16:18:31 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: avoid repeated setTransform; build the right offset.
    
    Change-Id: Iab153b25fa38f27742a052ad0892e3d55c2c04cc

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index a4b83aed9..2b8eb00db 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -93,6 +93,7 @@ L.CanvasTilePainter = L.Class.extend({
 		this._lastSize = mapSize;
 		this._lastMapSize = mapSize;
 		this._setCanvasSize(mapSize.x, mapSize.y);
+		this._canvasCtx.setTransform(1,0,0,1,0,0);
 	},
 
 	_setCanvasSize: function (widthCSSPx, heightCSSPx) {
@@ -129,7 +130,6 @@ L.CanvasTilePainter = L.Class.extend({
 	},
 
 	clear: function () {
-		this._canvasCtx.setTransform(1,0,0,1,0,0);
 		if (this._layer._debug)
 			this._canvasCtx.fillStyle = 'rgba(255, 0, 0, 0.5)';
 		else
@@ -171,15 +171,9 @@ L.CanvasTilePainter = L.Class.extend({
 			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;
-
-			this._canvasCtx.setTransform(1,0,
-						     0,1,
-						     -topLeft.x, -topLeft.y);
+			var offset = paneBounds.getTopLeft(); // allocates
+			offset.x = Math.min(offset.x, viewBounds.min.x);
+			offset.y = Math.min(offset.y, viewBounds.min.y);
 
 			// intersect - to avoid state thrash through clipping
 			var crop = new L.Bounds(tileBounds.min, tileBounds.max);
@@ -195,7 +189,8 @@ L.CanvasTilePainter = L.Class.extend({
 						  crop.min.x - tileBounds.min.x,
 						  crop.min.y - tileBounds.min.y,
 						  cropWidth, cropHeight,
-						  crop.min.x, crop.min.y,
+						  crop.min.x - offset.x,
+						  crop.min.y - offset.y,
 						  cropWidth, cropHeight);
 			if (this._layer._debug)
 			{
@@ -211,7 +206,6 @@ L.CanvasTilePainter = L.Class.extend({
 			return;
 		}
 		var splitPos = this._layer._cssPixelsToCore(splitPanesContext.getSplitPos());
-		this._canvasCtx.setTransform(1,0,0,1,0,0);
 		this._canvasCtx.strokeStyle = 'red';
 		this._canvasCtx.strokeRect(0, 0, splitPos.x, splitPos.y);
 	},
commit 5367d18d3d152ee7bdc5415aea2dcaca18e40438
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Sep 8 16:03:34 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: use sub image blitting instead of clipping.
    
    Avoids thrashing the canvas rendering context / clip state.
    
    Change-Id: I547ce22a171874cd7be3a0fac50b4afc56faf084

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index ab40e653a..a4b83aed9 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -177,15 +177,26 @@ L.CanvasTilePainter = L.Class.extend({
 			if (topLeft.y)
 				topLeft.y = viewBounds.min.y;
 
-			this._canvasCtx.setTransform(1,0,0,1,-topLeft.x, -topLeft.y);
-
-			// create a clip for the pane/view.
-			this._canvasCtx.beginPath();
-			var paneSize = paneBounds.getSize();
-			this._canvasCtx.rect(paneBounds.min.x, paneBounds.min.y, paneSize.x + 1, paneSize.y + 1);
-			this._canvasCtx.clip();
-
-			this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y);
+			this._canvasCtx.setTransform(1,0,
+						     0,1,
+						     -topLeft.x, -topLeft.y);
+
+			// intersect - to avoid state thrash through clipping
+			var crop = new L.Bounds(tileBounds.min, tileBounds.max);
+			crop.min.x = Math.max(paneBounds.min.x, tileBounds.min.x);
+			crop.min.y = Math.max(paneBounds.min.y, tileBounds.min.y);
+			crop.max.x = Math.min(paneBounds.max.x, tileBounds.max.x);
+			crop.max.y = Math.min(paneBounds.max.y, tileBounds.max.y);
+
+			var cropWidth = crop.max.x - crop.min.x;
+			var cropHeight = crop.max.y - crop.min.y;
+
+			this._canvasCtx.drawImage(tile.el,
+						  crop.min.x - tileBounds.min.x,
+						  crop.min.y - tileBounds.min.y,
+						  cropWidth, cropHeight,
+						  crop.min.x, crop.min.y,
+						  cropWidth, cropHeight);
 			if (this._layer._debug)
 			{
 				this._canvasCtx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
commit cee264f971d697a94dc9216d435c7a6b7605f15d
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Sep 8 16:03:15 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: round view co-ordinates to the real pixels we need.
    
    Change-Id: I768cd9015da1f1301f3ddad242130d4eddb426d1

diff --git a/loleaflet/src/geometry/Bounds.js b/loleaflet/src/geometry/Bounds.js
index 8dacdc832..e9ac075e8 100644
--- a/loleaflet/src/geometry/Bounds.js
+++ b/loleaflet/src/geometry/Bounds.js
@@ -83,6 +83,13 @@ L.Bounds.prototype = {
 		        (this.min.y + this.max.y) / 2, round);
 	},
 
+	round: function() {
+		this.min.x = Math.round(this.min.x);
+		this.min.y = Math.round(this.min.y);
+		this.max.x = Math.round(this.max.x);
+		this.max.y = Math.round(this.max.y);
+	},
+
 	getBottomLeft: function () { // -> Point
 		return new L.Point(this.min.x, this.max.y);
 	},
diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index af8a7fcbc..ab40e653a 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -164,6 +164,10 @@ L.CanvasTilePainter = L.Class.extend({
 			var paneBounds = this._layer._cssBoundsToCore(ctx.paneBoundsList[i]);
 			var viewBounds = this._layer._cssBoundsToCore(ctx.viewBounds);
 
+			// into real pixel-land ...
+			paneBounds.round();
+			viewBounds.round();
+
 			if (!paneBounds.intersects(tileBounds))
 				continue;
 
commit fdfb7fd9d0249c284db209907689e29ca8f3b631
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Sep 8 15:25:09 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: avoid lots of canvas context save/restores.
    
    Change-Id: Ib813686ef7d495e660ad8fa3b545391180b9e019

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 6d6aacecd..af8a7fcbc 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -129,14 +129,12 @@ L.CanvasTilePainter = L.Class.extend({
 	},
 
 	clear: function () {
-		this._canvasCtx.save();
-		this._canvasCtx.scale(1, 1);
+		this._canvasCtx.setTransform(1,0,0,1,0,0);
 		if (this._layer._debug)
 			this._canvasCtx.fillStyle = 'rgba(255, 0, 0, 0.5)';
 		else
 			this._canvasCtx.fillStyle = 'white';
 		this._canvasCtx.fillRect(0, 0, this._width, this._height);
-		this._canvasCtx.restore();
 	},
 
 	// Details of tile areas to render
@@ -175,9 +173,7 @@ L.CanvasTilePainter = L.Class.extend({
 			if (topLeft.y)
 				topLeft.y = viewBounds.min.y;
 
-			this._canvasCtx.save();
-			this._canvasCtx.scale(1, 1);
-			this._canvasCtx.translate(-topLeft.x, -topLeft.y);
+			this._canvasCtx.setTransform(1,0,0,1,-topLeft.x, -topLeft.y);
 
 			// create a clip for the pane/view.
 			this._canvasCtx.beginPath();
@@ -191,7 +187,6 @@ L.CanvasTilePainter = L.Class.extend({
 				this._canvasCtx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
 				this._canvasCtx.strokeRect(tile.coords.x, tile.coords.y, 256, 256);
 			}
-			this._canvasCtx.restore();
 		}
 	},
 
@@ -201,11 +196,9 @@ L.CanvasTilePainter = L.Class.extend({
 			return;
 		}
 		var splitPos = this._layer._cssPixelsToCore(splitPanesContext.getSplitPos());
-		this._canvasCtx.save();
-		this._canvasCtx.scale(1, 1);
+		this._canvasCtx.setTransform(1,0,0,1,0,0);
 		this._canvasCtx.strokeStyle = 'red';
 		this._canvasCtx.strokeRect(0, 0, splitPos.x, splitPos.y);
-		this._canvasCtx.restore();
 	},
 
 	_updateWithRAF: function () {
commit 69ccdb6b4bc0e1b39117173baad73996e37681f3
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Tue Sep 8 13:52:33 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    Split lines only in the corner when set to 0
    
    Change-Id: I6192219cede2d0888ecd77236f72ff734d99d778

diff --git a/loleaflet/src/layer/vector/SplitterLine.js b/loleaflet/src/layer/vector/SplitterLine.js
index 344b91625..547663fe7 100644
--- a/loleaflet/src/layer/vector/SplitterLine.js
+++ b/loleaflet/src/layer/vector/SplitterLine.js
@@ -2,7 +2,7 @@
 /*
  * L.SplitterLine is a draggable L.Rectangle to be used as control for split-panes.
  */
-
+/* global $ */
 L.SplitterLine = L.Rectangle.extend({
 
 	options: {
@@ -43,9 +43,15 @@ L.SplitterLine = L.Rectangle.extend({
 		var xmin = isHoriz ? splitPos.x - thickness/2 : -size.x;
 		var xmax = isHoriz ? splitPos.x + thickness/2 : size.x;
 
+		if (!this._dragStarted && splitPos.y == 0 && !isHoriz)
+			xmax = thickness/2;
+
 		var ymin = !isHoriz ? splitPos.y - thickness/2 : -size.y;
 		var ymax = !isHoriz ? splitPos.y + thickness/2 : size.y;
 
+		if (!this._dragStarted && splitPos.x == 0 && isHoriz)
+			ymax = thickness/2;
+
 		return new L.LatLngBounds(
 			map.unproject(new L.Point(xmin, ymin)),
 			map.unproject(new L.Point(xmax, ymax))
@@ -66,6 +72,7 @@ L.SplitterLine = L.Rectangle.extend({
 		}.bind(this));
 
 		this.addClass('leaflet-pane-splitter');
+		$('.leaflet-pane-splitter').parent().css('overflow', 'visible');
 	},
 
 	_onDragStart: function(evt) {
@@ -78,6 +85,8 @@ L.SplitterLine = L.Rectangle.extend({
 		this._dragStarted = true;
 		L.DomEvent.stop(evt);
 
+		this.setBounds(this._calculateLatLngBounds());
+
 		this._pathNodeCollection.forEachNode(function (nodeData) {
 			var node = nodeData.getNode();
 			L.DomEvent.on(node, 'mousemove', this._onDrag, this);
commit c1ac22da32cd8edd73117fc9b5fae961c9a5da7b
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Thu Sep 3 23:19:13 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: Preserving of the top left cell should be desktop-only.
    
    On mobile, the center of the zooming has to be according to the center
    of the pinch-to-zoom, ie. the center has to be taken into account.
    
    Change-Id: I3ba2ea90b7bac9bc1ba27f8068ea7ed6bbb4910d

diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index b067579de..20f495114 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -485,20 +485,22 @@ L.Map = L.Evented.extend({
 			// for spreadsheets, when the document is smaller than the viewing area
 			// we want it to be glued to the row/column headers instead of being centered
 			this._docLayer._checkSpreadSheetBounds(zoom);
-			var calcLayer = this._docLayer;
-			if (calcLayer.options.sheetGeometryDataEnabled && calcLayer.sheetGeometry) {
-				var sheetGeom = calcLayer.sheetGeometry;
-				var cellRange = sheetGeom.getViewCellRange();
-				var col = cellRange.columnrange.start, row = cellRange.rowrange.start;
-				var zoomScaleAbs = this.zoomToFactor(zoom);
+			if (window.mode.isDesktop()) {
+				var calcLayer = this._docLayer;
+				if (calcLayer.options.sheetGeometryDataEnabled && calcLayer.sheetGeometry) {
+					var sheetGeom = calcLayer.sheetGeometry;
+					var cellRange = sheetGeom.getViewCellRange();
+					var col = cellRange.columnrange.start, row = cellRange.rowrange.start;
+					var zoomScaleAbs = this.zoomToFactor(zoom);
 
-				var newTopLeftPx = sheetGeom.getCellRect(col, row, zoomScaleAbs).getTopLeft();
-				var moveByPoint = this._getTopLeftPoint(curCenter, zoom).subtract(newTopLeftPx);
+					var newTopLeftPx = sheetGeom.getCellRect(col, row, zoomScaleAbs).getTopLeft();
+					var moveByPoint = this._getTopLeftPoint(curCenter, zoom).subtract(newTopLeftPx);
 
-				// move the center (which is in LatLng) by the computed amount of pixels
-				var newCenterLatLng = this.unproject(this.project(curCenter, zoom).subtract(moveByPoint), zoom);
+					// move the center (which is in LatLng) by the computed amount of pixels
+					var newCenterLatLng = this.unproject(this.project(curCenter, zoom).subtract(moveByPoint), zoom);
 
-				return this.setView(newCenterLatLng, zoom, {zoom: options});
+					return this.setView(newCenterLatLng, zoom, {zoom: options});
+				}
 			}
 		}
 
commit 367a0b75fba01745d67cf16cf0d10e52c59c7de5
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Sep 1 21:35:35 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: paint invalid tiles until their replacement arrives.
    
    This avoids display corruption when panning, whereby stale/old
    canvas content would continue to be rendered in the 'holes'
    where invalid tiles were not rendered.
    
    Change-Id: Ic886c0924c5a930116b1437c8e0cf35726ab76a5

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 8643f8bf7..6d6aacecd 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -253,7 +253,7 @@ L.CanvasTilePainter = L.Class.extend({
 			!splitPosChanged &&
 			!scaleChanged);
 
-		console.debug('Tile size: ' + this._layer._getTileSize());
+//		console.debug('Tile size: ' + this._layer._getTileSize());
 
 		if (skipUpdate)
 			return;
@@ -306,10 +306,14 @@ L.CanvasTilePainter = L.Class.extend({
 
 					var key = coords.key();
 					var tile = this._layer._tiles[key];
-					var invalid = tile && tile._invalidCount && tile._invalidCount > 0;
-					if (tile && tile.loaded && !invalid) {
+//					var invalid = tile && tile._invalidCount && tile._invalidCount > 0;
+					if (tile && tile.loaded) {
 						this.paint(tile, ctx);
 					}
+/*					else
+						console.log('missing tile at ' + i + ', ' + j + ' ' +
+							    tile + ' ' + (tile && tile.loaded) + ' ' +
+							    (tile ? tile._invalidCount : -42) + ' ' + invalid); */
 				}
 			}
 		}
commit 0184833ace3805f5c2c929c9127f1c68edc3c153
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Sep 1 16:53:02 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc tiles: don't send un-necessary zoom / visible area changes.
    
    Lots of redundant zoom messages seem unhelpful.
    
    Change-Id: I944a3202739adfc89aab81902b467a4e34977202

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 8ef3cb886..8643f8bf7 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -697,9 +697,8 @@ L.CanvasTileLayer = L.TileLayer.extend({
 			}
 		}
 
-		this._sendClientVisibleArea(true);
-
-		this._sendClientZoom(true);
+		this._sendClientVisibleArea();
+		this._sendClientZoom();
 
 		if (queue.length !== 0) {
 			if (cancelTiles) {
commit 3b7595701168199b2d8aa8e302a2ce866aa6c434
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Sep 1 16:24:18 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: ensure that the fraction width rounds to the pixel width.
    
    Slave CSS geometry from integral canvas pixels, don't attempt the
    reverse.
    
    Change-Id: I369ed1bea3c4a5a199192aa1e84bb4e03dcb2e94

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 4983fef2a..8ef3cb886 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -96,11 +96,20 @@ L.CanvasTilePainter = L.Class.extend({
 	},
 
 	_setCanvasSize: function (widthCSSPx, heightCSSPx) {
-		this._canvas.style.width = widthCSSPx + 'px';
-		this._canvas.style.height = heightCSSPx + 'px';
-		this._canvas.width = Math.floor(widthCSSPx * this._dpiScale);
-		this._canvas.height = Math.floor(heightCSSPx * this._dpiScale);
+		var pixWidth = Math.floor(widthCSSPx * this._dpiScale);
+		var pixHeight = Math.floor(heightCSSPx * this._dpiScale);
 
+		// real pixels have to be integral
+		this._canvas.width = pixWidth;
+		this._canvas.height = pixHeight;
+
+		// CSS pixels can be fractional, but need to round to the same real pixels
+		var cssWidth = pixWidth / this._dpiScale; // NB. beware
+		var cssHeight = pixHeight / this._dpiScale;
+		this._canvas.style.width = cssWidth.toFixed(4) + 'px';
+		this._canvas.style.height = cssHeight.toFixed(4) + 'px';
+
+		// FIXME: is this a good idea ? :
 		this._width = parseInt(this._canvas.style.width);
 		this._height = parseInt(this._canvas.style.height);
 		this.clear();
commit 1be56e18a52eb783ba790a56293dc99ded0ed0c4
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Tue Sep 1 01:39:07 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: Fix occasional off-by-one error that results in a blurry canvas.
    
    The core of the fix is in _getNewPixelOrigin() where the round() behaves
    non-predictably / inconsistently with the rest of the code, causing
    random off-by-one error that shows (or not) depending on the window
    size.
    
    The biggest problem of this is that this off-by-one is then multiplied
    somewhere by the zoom factor, causing the canvas being completely
    blurry; but eventually when the user clicked into the sheet, it
    'magically' fixed itself.
    
    The rest of the changes (in setZoom()) should actually do the same thing
    as the previous code, but using existing methods, instead of computing
    the shifts manually.
    
    Change-Id: If0ecb1301b7c1e65cfe8126385ef959c584c5d16

diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 9528f9aff..b067579de 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -479,6 +479,8 @@ L.Map = L.Evented.extend({
 			this._zoom = this._limitZoom(zoom);
 			return this;
 		}
+
+		var curCenter = this.getCenter();
 		if (this._docLayer && this._docLayer._docType === 'spreadsheet') {
 			// for spreadsheets, when the document is smaller than the viewing area
 			// we want it to be glued to the row/column headers instead of being centered
@@ -488,14 +490,18 @@ L.Map = L.Evented.extend({
 				var sheetGeom = calcLayer.sheetGeometry;
 				var cellRange = sheetGeom.getViewCellRange();
 				var col = cellRange.columnrange.start, row = cellRange.rowrange.start;
-				var zoomScaleAbs = Math.pow(1.2, (zoom - this.options.zoom));
+				var zoomScaleAbs = this.zoomToFactor(zoom);
+
 				var newTopLeftPx = sheetGeom.getCellRect(col, row, zoomScaleAbs).getTopLeft();
-				var newCenterPx = newTopLeftPx.add(this.getSize().divideBy(2)._floor());
-				var newCenterLatLng = this.unproject(newCenterPx, zoom);
+				var moveByPoint = this._getTopLeftPoint(curCenter, zoom).subtract(newTopLeftPx);
+
+				// move the center (which is in LatLng) by the computed amount of pixels
+				var newCenterLatLng = this.unproject(this.project(curCenter, zoom).subtract(moveByPoint), zoom);
+
 				return this.setView(newCenterLatLng, zoom, {zoom: options});
 			}
 		}
-		var curCenter = this.getCenter();
+
 		if (this._docLayer && this._docLayer._visibleCursor && this.getBounds().contains(this._docLayer._visibleCursor.getCenter())) {
 			// Calculate new center after zoom. The intent is that the caret
 			// position stays the same.
@@ -1686,13 +1692,13 @@ L.Map = L.Evented.extend({
 		var pixelOrigin = center && zoom !== undefined ?
 			this._getNewPixelOrigin(center, zoom) :
 			this.getPixelOrigin();
+
 		return pixelOrigin.subtract(this._getMapPanePos());
 	},
 
 	_getNewPixelOrigin: function (center, zoom) {
 		var viewHalf = this.getSize()._divideBy(2);
-		// TODO round on display, not calculation to increase precision?
-		return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round();
+		return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._floor();
 	},
 
 	_latLngToNewLayerPoint: function (latlng, zoom, center) {
commit 77599a926665093ae803f1da4b718ca86d0d5b0a
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Aug 28 16:05:04 2020 +0100
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc tiles: connect debug to global setting.
    
    Change-Id: I0db008ac40020c9173d37969aa6c23b3a1696f79

diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js
index 35f23437a..4983fef2a 100644
--- a/loleaflet/src/layer/tile/CanvasTileLayer.js
+++ b/loleaflet/src/layer/tile/CanvasTileLayer.js
@@ -36,10 +36,6 @@ L.TileCoordData.parseKey = function (keyString) {
 
 L.CanvasTilePainter = L.Class.extend({
 
-	options: {
-		debug: true,
-	},
-
 	initialize: function (layer) {
 		this._layer = layer;
 		this._canvas = this._layer._canvas;
@@ -126,8 +122,8 @@ L.CanvasTilePainter = L.Class.extend({
 	clear: function () {
 		this._canvasCtx.save();
 		this._canvasCtx.scale(1, 1);
-		if (this.options.debug)
-			this._canvasCtx.fillStyle = 'red';
+		if (this._layer._debug)
+			this._canvasCtx.fillStyle = 'rgba(255, 0, 0, 0.5)';
 		else
 			this._canvasCtx.fillStyle = 'white';
 		this._canvasCtx.fillRect(0, 0, this._width, this._height);
@@ -181,9 +177,9 @@ L.CanvasTilePainter = L.Class.extend({
 			this._canvasCtx.clip();
 
 			this._canvasCtx.drawImage(tile.el, tile.coords.x, tile.coords.y);
-			if (this.options.debug)
+			if (this._layer._debug)
 			{
-				this._canvasCtx.strokeStyle = 'red';
+				this._canvasCtx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
 				this._canvasCtx.strokeRect(tile.coords.x, tile.coords.y, 256, 256);
 			}
 			this._canvasCtx.restore();
@@ -273,13 +269,13 @@ L.CanvasTilePainter = L.Class.extend({
 		this._topLeft = newTopLeft;
 		this._paintWholeCanvas();
 
-		if (this.options.debug)
+		if (this._layer._debug)
 			this._drawSplits();
 	},
 
 	_paintWholeCanvas: function () {
 
-		if (this.options.debug)
+		if (this._layer._debug)
 			this.clear();
 
 		var zoom = this._lastZoom || Math.round(this._map.getZoom());
commit c82d14af520b41683cb731fba3a37fbefd14f1e8
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Wed Aug 26 15:15:55 2020 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    calc canvas: Keep the document zoom separate from the browser zoom.
    
    With this, if you increase or decrease the browser zoom, the document
    zoom still stays the same.
    
    Before this, when you had eg. 100% document zoom and 150% browser zoom
    and try to zoom out, it actually zooms in instead, because the browser's
    zoom is added to the mix; and it displays the wrong value in the
    dropdown.  Even worse, to get the 100% again, you have to choose 80% so
    that the correction for the browser zoom is added, resulting in the
    100%.
    
    We should keep both the document and browser zoom separately.  The
    questions is then whether to combine them later for the actual document
    rendering; I believe we should not, but even if we should, we cannot do
    it directly in the setZoom() method, but instead closer to the painting
    itself.
    
    Change-Id: Ib7f3d2ae8b4e6e6086f14e933b215c32326c6be6

diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 3e5ce2a52..9528f9aff 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -466,19 +466,6 @@ L.Map = L.Evented.extend({
 		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 = this.zoomToFactor(zoom);
-
-		var dpiScale = this._docLayer ? this._docLayer.canvasDPIScale() : L.getDpiScaleFactor(true /* useExactDPR */);
-
-		var zoomScale = clientZoomScale * dpiScale;
-		var nearestZoom = this.factorToZoom(zoomScale);
-		nearestZoom = this._limitZoom(nearestZoom);
-
-		return nearestZoom;
-	},
-
 	setZoom: function (zoom, options) {
 
 		if (this._docLayer instanceof L.CanvasTileLayer) {
@@ -486,8 +473,6 @@ L.Map = L.Evented.extend({
 				zoom = this._clientZoom || this.options.zoom;
 			else
 				this._clientZoom = zoom;
-
-			zoom = this.findNearestProductZoom(zoom);
 		}
 
 		if (!this._loaded) {
commit 74d71e870d2aceb204b6b9f426381c24abaa24c6
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Tue Aug 25 12:01:51 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    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 c98d2fef4..eedf8966a 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -502,17 +502,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() {
@@ -566,8 +565,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 75f662fbd7eea552d0693aad4092e4e4412c5691
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Tue Aug 25 11:55:25 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    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 7c35a8ce5..3e5ce2a52 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -481,8 +481,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 baef4f78f4009c160e7430887072b3ccc9cdd669
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Tue Aug 25 11:36:03 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    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 4639acd96..6027c47da 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 80ccbbe1b..fb53bfce6 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 c7b0ef1f2..c98d2fef4 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());
@@ -476,7 +475,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();
@@ -742,7 +741,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 3efdbe43f..7c35a8ce5 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -457,12 +457,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 f86d70901e25d9f4be4b68696f49251744cdc1e5
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 22:34:27 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    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 417cf0e16..c7b0ef1f2 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());
@@ -475,7 +476,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();
@@ -741,9 +742,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);
@@ -1223,12 +1225,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');
@@ -1241,7 +1243,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);
@@ -1285,10 +1287,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) {
@@ -1429,7 +1431,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));
@@ -1437,8 +1439,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);
@@ -1455,13 +1457,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);
 	},
@@ -1593,7 +1595,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;
@@ -1601,17 +1603,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.
@@ -1628,7 +1635,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 (
@@ -1636,17 +1643,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
@@ -1657,23 +1664,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
@@ -1685,7 +1698,7 @@ L.SheetDimension = L.Class.extend({
 			return undefined;
 		}
 
-		return this._getElementDataFromSpanByIndex(index, span, useDevicePixels);
+		return this._getElementDataFromSpanByIndex(index, span, useCorePixels);
 	},
 
 	getElementDataAny: function (index, unitName) {
@@ -1698,9 +1711,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.
@@ -1710,20 +1723,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
 			};
 		}
 
@@ -1735,12 +1748,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)
 		};
 	},
 
@@ -1769,8 +1782,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;
 
@@ -1837,8 +1849,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(),
@@ -1900,9 +1912,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
@@ -1935,7 +1947,7 @@ L.SheetDimension = L.Class.extend({
 	isUnitSupported: function (unitName) {
 		return (
 			unitName === 'csspixels' ||
-			unitName === 'devpixels' ||
+			unitName === 'corepixels' ||
 			unitName === 'tiletwips' ||
 			unitName === 'printtwips'
 		);
@@ -1947,12 +1959,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';
 		}
 
@@ -1968,12 +1980,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 2bf76665a2b6fb50b5b1a0ad44046a9afc0a408c
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 22:31:16 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    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 aee950331..50dd0240c 100644
--- a/loleaflet/css/spreadsheet.css
+++ b/loleaflet/css/spreadsheet.css
@@ -129,6 +129,7 @@
 .spreadsheet-header-columns {
 	display: inline-block;
 	white-space: nowrap;
+	width: 100%;
 	height: 100%;
 	border-spacing: 0px !important;
 	position: relative;
@@ -171,6 +172,7 @@
 
 .spreadsheet-header-rows {
 	width: 100%;
+	height: 100%;
 	border-spacing: 0px !important;
 	position: relative;
 	margin: 0px;
commit cf12bb19039ef199c3baf1f3332a709142361807
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Mon Aug 24 22:12:18 2020 +0530
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Thu Sep 17 15:03:01 2020 +0200

    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 d6eccf5b1..4639acd96 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({

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list