diff options
author | Gökay Şatır <gokaysatir@collabora.com> | 2020-12-01 14:12:10 +0300 |
---|---|---|
committer | Gökay Şatır <gokaysatir@collabora.com> | 2020-12-01 14:12:10 +0300 |
commit | c8945d42965ebd33157a09c064e91179e673462c (patch) | |
tree | b9d71f38e93dadd8774da0717c7249169500293d | |
parent | Control-Headers: Drop canvasDPIScale function. (diff) | |
download | online-private/gokay/canvastilelayer3.tar.gz online-private/gokay/canvastilelayer3.zip |
CanvasTileLayer usage for Writer and Impress is improved. Some other changes for Calc.
private/gokay/canvastilelayer3
Control.ColumnHeader.js:
* Canvas scaling is removed. Shape lengths and positions are multiplied with _dpiScale.
* Canvas drawing method fillRect is replaced with rect & beginPath.
* ctx.save() and ctx.restore() are removed.
Control.Header.js:
* Font size is adjusted according to pixelratio.
* Element positions are now calculated according to previous one.
Control.RowHeader.js:
* Scaling, save() and restore() functions are removed.
* Variables are simplified while debugging. starY and startX are more meaningful then startOrt and startPar.
* Some unnecessary variables are removed.
* fillRect is replaced with rect and fill.
Control.Scroll.js:
* _onScroll function should work only for desktop. On mobile, it causes a bug that startPx (->inside Control.Header.js, update function) of header elements are pinned to zero.
Socket.js:
* White spaces are removed upon saving (editor feature).
* tileWidth and tileHeight adjustments are moved to this file, for early assignment.
SplitPangesContext.js:
* CSS pixel calculations are replaced with core pixel ones.
CalcTileLayer.js:
* Converter function (used in Control.Header, RowHeader and ColumnHeader) is replaced to use core pixels.
* posCorePx variable usage is removed. There is an error with every single iteration, then it sums up. FinalPosTwips is used instead. twips <-> pixel conversion is done when needed.
* _getElementDataAnyFromSpanByIndex is updated. Now variables are assigned using twips then converted to corePixels if asked.
* forEachInCorePixelRange function was using poscorepx variable. It is replaced with finalPosElementTwips. This function is called from only one other function.
* _getSpanAndIndexFromTwipsPos function is updated to use finalPosTwips.
* _searchByFinalPosTwips binary search function is introduced. Old one wasn't able to find the queried span.
CanvasTileLayer.js:
* paintSimple function is introduced. Painting with panes is buggy for Writer and Impress at current state.
* _initContainer function: tile width and height adjustments are moved into Socket.js file.
* _twipsToCorePixels and _corePixelsToTwips are introduced, i had to add them for conversions in Control.Header.js (i may have deleted these in previous commits).
* docPixelLimits and scrollPixelLimits are adjusted according to pixelRatio.
Signed-off-by: Gökay Şatır <gokaysatir@collabora.com>
Change-Id: Iab429133069c3266cda3070740b4476458d2b429
-rw-r--r-- | loleaflet/src/control/Control.ColumnHeader.js | 37 | ||||
-rw-r--r-- | loleaflet/src/control/Control.Header.js | 42 | ||||
-rw-r--r-- | loleaflet/src/control/Control.RowHeader.js | 58 | ||||
-rw-r--r-- | loleaflet/src/control/Control.Scroll.js | 3 | ||||
-rw-r--r-- | loleaflet/src/core/Socket.js | 16 | ||||
-rw-r--r-- | loleaflet/src/layer/SplitPanesContext.js | 12 | ||||
-rw-r--r-- | loleaflet/src/layer/tile/CalcTileLayer.js | 119 | ||||
-rw-r--r-- | loleaflet/src/layer/tile/CanvasTileLayer.js | 52 |
8 files changed, 200 insertions, 139 deletions
diff --git a/loleaflet/src/control/Control.ColumnHeader.js b/loleaflet/src/control/Control.ColumnHeader.js index 2f7727cb80..350c8f0371 100644 --- a/loleaflet/src/control/Control.ColumnHeader.js +++ b/loleaflet/src/control/Control.ColumnHeader.js @@ -39,8 +39,6 @@ L.Control.ColumnHeader = L.Control.Header.extend({ this._setCanvasHeight(); this._canvasBaseHeight = this._canvasHeight; - this._canvasContext.scale(this._dpiScale, this._dpiScale); - this._headerHeight = this._canvasHeight; L.Control.Header.colHeaderHeight = this._canvasHeight; @@ -222,7 +220,6 @@ L.Control.ColumnHeader = L.Control.Header.extend({ if (width <= 0) return; - ctx.save(); // background gradient var selectionBackgroundGradient = null; if (isHighlighted) { @@ -234,17 +231,18 @@ L.Control.ColumnHeader = L.Control.Header.extend({ // draw header/outline border separator if (this._headerHeight !== this._canvasHeight) { + ctx.beginPath(); ctx.fillStyle = this._borderColor; - ctx.fillRect(startPar, startOrt - this._borderWidth, width, this._borderWidth); + ctx.rect(startPar, startOrt - this._borderWidth, width, this._borderWidth); + ctx.fill(); } - // clip mask - ctx.beginPath(); - ctx.rect(startPar, startOrt, width, height); - ctx.clip(); // draw background + ctx.beginPath(); ctx.fillStyle = isHighlighted ? selectionBackgroundGradient : isOver ? this._hoverColor : this._backgroundColor; - ctx.fillRect(startPar, startOrt, width, height); + ctx.rect(startPar, startOrt, width, height); + ctx.fill(); + // draw resize handle var handleSize = this._resizeHandleSize; if (isCurrent && width > 2 * handleSize) { @@ -254,9 +252,14 @@ L.Control.ColumnHeader = L.Control.Header.extend({ var size = 2; var offset = 1; ctx.fillStyle = '#BBBBBB'; - ctx.fillRect(center - size - offset, y + 2, size, h - 4); - ctx.fillRect(center + offset, y + 2, size, h - 4); + ctx.beginPath(); + ctx.rect(center - size - offset, y + 2, size, h - 4); + ctx.fill(); + ctx.beginPath(); + ctx.rect(center + offset, y + 2, size, h - 4); + ctx.fill(); } + // draw text content ctx.fillStyle = isHighlighted ? this._selectionTextColor : this._textColor; ctx.font = this._font.getFont(); @@ -269,8 +272,9 @@ L.Control.ColumnHeader = L.Control.Header.extend({ ctx.fillText(content, endPar - (width / 2), startOrt + (height / 2) + 1); // draw row separator ctx.fillStyle = this._borderColor; - ctx.fillRect(endPar -1, startOrt, this._borderWidth, height); - ctx.restore(); + ctx.beginPath(); + ctx.rect(endPar -1, startOrt, this._borderWidth, height); + ctx.fill(); }, drawGroupControl: function (group) { @@ -286,9 +290,6 @@ L.Control.ColumnHeader = L.Control.Header.extend({ var startPar = this._headerInfo.docToHeaderPos(group.startPos); var height = group.endPos - group.startPos; - ctx.save(); - ctx.scale(this._dpiScale, this._dpiScale); - // clip mask ctx.beginPath(); ctx.rect(startPar, startOrt, height, headSize); @@ -328,7 +329,6 @@ L.Control.ColumnHeader = L.Control.Header.extend({ ctx.lineTo(startPar + headSize / 2, startOrt + 3 * headSize / 4); ctx.stroke(); } - ctx.restore(); }, drawLevelHeader: function(level) { @@ -339,8 +339,6 @@ L.Control.ColumnHeader = L.Control.Header.extend({ var startOrt = levelSpacing + (ctrlHeadSize + levelSpacing) * level; var startPar = this._cornerCanvas.width / this._dpiScale - (ctrlHeadSize + (L.Control.Header.rowHeaderWidth - ctrlHeadSize) / 2); - ctx.save(); - ctx.scale(this._dpiScale, this._dpiScale); ctx.fillStyle = this._hoverColor; ctx.fillRect(startPar, startOrt, ctrlHeadSize, ctrlHeadSize); ctx.strokeStyle = 'black'; @@ -352,7 +350,6 @@ L.Control.ColumnHeader = L.Control.Header.extend({ ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(level + 1, startPar + (ctrlHeadSize / 2), startOrt + (ctrlHeadSize / 2)); - ctx.restore(); }, getHeaderEntryBoundingClientRect: function (index) { diff --git a/loleaflet/src/control/Control.Header.js b/loleaflet/src/control/Control.Header.js index 22edf80f68..e86d0c1946 100644 --- a/loleaflet/src/control/Control.Header.js +++ b/loleaflet/src/control/Control.Header.js @@ -74,7 +74,7 @@ L.Control.Header = L.Control.extend({ var rate = fontHeight / fontSize; this._font = { _hdr: this, - _baseFontSize: fontSize * window.devicePixelRatio, + _baseFontSize: fontSize * this._dpiScale, _fontSizeRate: rate, _fontFamily: fontFamily, getFont: function() { @@ -93,7 +93,7 @@ L.Control.Header = L.Control.extend({ }; this._borderColor = L.DomUtil.getStyle(elem, 'border-top-color'); var borderWidth = L.DomUtil.getStyle(elem, 'border-top-width'); - this._borderWidth = Math.round(parseFloat(borderWidth)) * window.devicePixelRatio; + this._borderWidth = Math.round(parseFloat(borderWidth)) * this._dpiScale; this._cursor = L.DomUtil.getStyle(elem, 'cursor'); L.DomUtil.remove(elem); }, @@ -802,17 +802,16 @@ L.Control.Header.HeaderInfo = L.Class.extend({ this._hasSplits = false; this._splitIndex = 0; - var splitPos = 0; + this._splitPos = 0; if (splitPosContext) { - splitPos = this._isCol ? splitPosContext.getSplitPos().x : splitPosContext.getSplitPos().y; - var splitIndex = this._dimGeom.getIndexFromPos(splitPos + 1, 'corepixels'); + this._splitPos = this._isCol ? splitPosContext.getSplitPos().x : splitPosContext.getSplitPos().y; + var splitIndex = this._dimGeom.getIndexFromPos(this._splitPos + 1, 'corepixels'); if (splitIndex) { // Make sure splitPos is aligned to the cell boundary. - splitPos = this._dimGeom.getElementData(splitIndex).startpos; - this._splitPos = splitPos; + this._splitPos = this._dimGeom.getElementData(splitIndex).startpos; this._dimGeom.forEachInRange(0, splitIndex - 1, function (idx, data) { this._elements[idx] = { @@ -827,36 +826,29 @@ L.Control.Header.HeaderInfo = L.Class.extend({ this._hasSplits = true; this._splitIndex = splitIndex; - var freeStartPos = startPx + splitPos + 1; - var freeStartIndex = this._dimGeom.getIndexFromPos(freeStartPos + 1, 'corepixels'); - - startIdx = freeStartIndex; + var freeStartPos = startPx + this._splitPos + 1; + startIdx = this._dimGeom.getIndexFromPos(freeStartPos + 1, 'corepixels'); } } // first free index - var dataFirstFree = this._dimGeom.getElementData(startIdx); - var firstFreeEnd = dataFirstFree.startpos + dataFirstFree.size - startPx; - var firstFreeStart = splitPos; - var firstFreeSize = Math.max(0, firstFreeEnd - firstFreeStart); + var firstVisibleHeader = this._dimGeom.getElementData(startIdx); this._elements[startIdx] = { index: startIdx, - pos: firstFreeEnd, // end position on the header canvas - size: firstFreeSize, - origsize: dataFirstFree.size, + pos: firstVisibleHeader.startpos + firstVisibleHeader.size - startPx, // end position on the header canvas + size: Math.min(firstVisibleHeader.startpos + firstVisibleHeader.size - startPx - this._splitPos, firstVisibleHeader.size), + origsize: firstVisibleHeader.size, }; - + startPx = firstVisibleHeader.startpos + firstVisibleHeader.size - startPx; this._dimGeom.forEachInRange(startIdx + 1, endIdx, function (idx, data) { - var startpos = data.startpos - startPx; - var endpos = startpos + data.size; - var size = endpos - startpos; this._elements[idx] = { index: idx, - pos: endpos, // end position on the header canvas - size: size, - origsize: size, + pos: data.size + startPx, // end position on the header canvas + size: data.size, + origsize: data.size, }; + startPx += data.size; }.bind(this)); this._startIndex = startIdx; diff --git a/loleaflet/src/control/Control.RowHeader.js b/loleaflet/src/control/Control.RowHeader.js index 8e0a4e95af..e9f42fff59 100644 --- a/loleaflet/src/control/Control.RowHeader.js +++ b/loleaflet/src/control/Control.RowHeader.js @@ -39,7 +39,6 @@ L.Control.RowHeader = L.Control.Header.extend({ this._setCanvasWidth(); this._setCanvasHeight(); - this._canvasContext.scale(this._dpiScale, this._dpiScale); this._headerWidth = this._canvasWidth; L.Control.Header.rowHeaderWidth = this._canvasWidth; @@ -202,24 +201,20 @@ L.Control.RowHeader = L.Control.Header.extend({ var ctx = this._canvasContext; var content = entry.index + 1; - var startOrt = this._canvasWidth - this._headerWidth; - var startPar = entry.pos - entry.size; - var endPar = entry.pos; - var height = endPar - startPar; - var width = this._headerWidth; + var startX = this._canvasWidth - this._headerWidth; + var startY = entry.pos - entry.size; if (isHighlighted !== true && isHighlighted !== false) { isHighlighted = this.isHighlighted(entry.index); } - if (height <= 0) + if (entry.size <= 0) return; - ctx.save(); // background gradient var selectionBackgroundGradient = null; if (isHighlighted) { - selectionBackgroundGradient = ctx.createLinearGradient(0, startPar, 0, startPar + height); + selectionBackgroundGradient = ctx.createLinearGradient(0, startY, 0, startY + entry.size); selectionBackgroundGradient.addColorStop(0, this._selectionBackgroundGradient[0]); selectionBackgroundGradient.addColorStop(0.5, this._selectionBackgroundGradient[1]); selectionBackgroundGradient.addColorStop(1, this._selectionBackgroundGradient[2]); @@ -227,39 +222,47 @@ L.Control.RowHeader = L.Control.Header.extend({ // draw header/outline border separator if (this._headerWidth !== this._canvasWidth) { + ctx.beginPath(); ctx.fillStyle = this._borderColor; - ctx.fillRect(startOrt - this._borderWidth, startPar, this._borderWidth, height); + ctx.rect(startX - this._borderWidth, startY, this._borderWidth, entry.size); + ctx.fill(); } - // clip mask - ctx.beginPath(); - ctx.rect(startOrt, startPar, width, height); - ctx.clip(); // draw background + ctx.beginPath(); ctx.fillStyle = isHighlighted ? selectionBackgroundGradient : isOver ? this._hoverColor : this._backgroundColor; - ctx.fillRect(startOrt, startPar, width, height); + ctx.rect(startX, startY, this._headerWidth, entry.size); + ctx.fill(); + // draw resize handle var handleSize = this._resizeHandleSize; - if (isCurrent && height > 2 * handleSize) { - var center = startPar + height - handleSize / 2; - var x = startOrt + 2; - var w = width - 4; + if (isCurrent && entry.size > 2 * handleSize) { + var center = startY + entry.size - handleSize / 2; + var x = startX + 2; + var w = this._headerWidth - 4; var size = 2; var offset = 1; ctx.fillStyle = '#BBBBBB'; - ctx.fillRect(x + 2, center - size - offset, w - 4, size); - ctx.fillRect(x + 2, center + offset, w - 4, size); + ctx.beginPath(); + ctx.rect(x + 2, center - size - offset, w - 4, size); + ctx.fill(); + ctx.beginPath(); + ctx.rect(x + 2, center + offset, w - 4, size); + ctx.fill(); } + // draw text content ctx.fillStyle = isHighlighted ? this._selectionTextColor : this._textColor; ctx.font = this._font.getFont(); ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; - ctx.fillText(content, startOrt + (width / 2), endPar - (height / 2)); + ctx.fillText(content, startX + (this._headerWidth / 2), entry.pos - (entry.size / 2)); + // draw row separator + ctx.beginPath(); ctx.fillStyle = this._borderColor; - ctx.fillRect(startOrt, endPar - 1, width , this._borderWidth); - ctx.restore(); + ctx.rect(startX, entry.pos - 1, this._headerWidth , this._borderWidth); + ctx.fill(); }, drawGroupControl: function (group) { @@ -275,9 +278,6 @@ L.Control.RowHeader = L.Control.Header.extend({ var startPar = this._headerInfo.docToHeaderPos(group.startPos); var height = group.endPos - group.startPos; - ctx.save(); - ctx.scale(this._dpiScale, this._dpiScale); - // clip mask ctx.beginPath(); ctx.rect(startOrt, startPar, headSize, height); @@ -317,7 +317,6 @@ L.Control.RowHeader = L.Control.Header.extend({ ctx.lineTo(startOrt + headSize / 2, startPar + 3 * headSize / 4); ctx.stroke(); } - ctx.restore(); }, drawLevelHeader: function(level) { @@ -328,8 +327,6 @@ L.Control.RowHeader = L.Control.Header.extend({ var startOrt = levelSpacing + (ctrlHeadSize + levelSpacing) * level; var startPar = this._cornerCanvas.height / this._dpiScale - (ctrlHeadSize + (L.Control.Header.colHeaderHeight - ctrlHeadSize) / 2); - ctx.save(); - ctx.scale(this._dpiScale, this._dpiScale); ctx.fillStyle = this._hoverColor; ctx.fillRect(startOrt, startPar, ctrlHeadSize, ctrlHeadSize); ctx.strokeStyle = 'black'; @@ -341,7 +338,6 @@ L.Control.RowHeader = L.Control.Header.extend({ ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(level + 1, startOrt + (ctrlHeadSize / 2), startPar + (ctrlHeadSize / 2)); - ctx.restore(); }, getHeaderEntryBoundingClientRect: function (index) { diff --git a/loleaflet/src/control/Control.Scroll.js b/loleaflet/src/control/Control.Scroll.js index 8f03ef579f..e1579ad5c1 100644 --- a/loleaflet/src/control/Control.Scroll.js +++ b/loleaflet/src/control/Control.Scroll.js @@ -123,7 +123,8 @@ L.Control.Scroll = L.Control.extend({ _onScroll: function (e) { if (this._map._docLayer._docType === 'spreadsheet') { - this._onCalcScroll(e); + if (window.mode.isDesktop()) + this._onCalcScroll(e); return; } diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index 177acebbd4..c991d6e5b8 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -247,9 +247,9 @@ L.Socket = L.Class.extend({ _logSocket: function(type, msg) { var fullDebug = this._map._docLayer && this._map._docLayer._debug; - if (fullDebug) + if (fullDebug) this._map._docLayer._debugSetPostMessage(type,msg); - + if (!window.protocolDebug && !fullDebug) return; @@ -1001,16 +1001,16 @@ L.Socket = L.Class.extend({ if (command.type === 'text') { docLayer = new L.WriterTileLayer('', { permission: this._map.options.permission, - tileWidthTwips: tileWidthTwips, - tileHeightTwips: tileHeightTwips, + tileWidthTwips: tileWidthTwips / window.devicePixelRatio, + tileHeightTwips: tileHeightTwips / window.devicePixelRatio, docType: command.type }); } else if (command.type === 'spreadsheet') { docLayer = new L.CalcTileLayer('', { permission: this._map.options.permission, - tileWidthTwips: tileWidthTwips, - tileHeightTwips: tileHeightTwips, + tileWidthTwips: tileWidthTwips / window.devicePixelRatio, + tileHeightTwips: tileHeightTwips / window.devicePixelRatio, docType: command.type }); @@ -1039,8 +1039,8 @@ L.Socket = L.Class.extend({ } docLayer = new L.ImpressTileLayer('', { permission: this._map.options.permission, - tileWidthTwips: tileWidthTwips, - tileHeightTwips: tileHeightTwips, + tileWidthTwips: tileWidthTwips / window.devicePixelRatio, + tileHeightTwips: tileHeightTwips / window.devicePixelRatio, docType: command.type }); } diff --git a/loleaflet/src/layer/SplitPanesContext.js b/loleaflet/src/layer/SplitPanesContext.js index b75272221d..fefa106779 100644 --- a/loleaflet/src/layer/SplitPanesContext.js +++ b/loleaflet/src/layer/SplitPanesContext.js @@ -193,10 +193,10 @@ L.SplitPanesContext = L.Class.extend({ return paneStatusList; }, - // returns all the pane rectangles for the provided full-map area (all in CSS pixels). + // returns all the pane rectangles for the provided full-map area (all in core pixels). getPxBoundList: function (pxBounds) { if (!pxBounds) { - pxBounds = this._map.getPixelBounds(); + pxBounds = this._map.getPixelBoundsCore(); } var topLeft = pxBounds.getTopLeft(); var bottomRight = pxBounds.getBottomRight(); @@ -240,14 +240,14 @@ L.SplitPanesContext = L.Class.extend({ var docLayer = this._docLayer; return bounds.map(function (bound) { return new L.Bounds( - docLayer._pixelsToTwips(bound.min), - docLayer._pixelsToTwips(bound.max) + docLayer._corePixelsToTwips(bound.min), + docLayer._corePixelsToTwips(bound.max) ); }); }, getClientVisibleArea: function () { - var pixelBounds = this._map.getPixelBounds(); + var pixelBounds = this._map.getPixelBoundsCore(); var fullSize = pixelBounds.getSize(); var cursorPos = this._docLayer.getCursorPos(); cursorPos._floor(); @@ -277,7 +277,7 @@ L.SplitPanesContext = L.Class.extend({ }, intersectsVisible: function (areaPx) { - var pixBounds = this._map.getPixelBounds(); + var pixBounds = this._map.getPixelBoundsCore(); var boundList = this.getPxBoundList(pixBounds); for (var i = 0; i < boundList.length; ++i) { if (areaPx.intersects(boundList[i])) { diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js index af2e5dd5aa..7122c09876 100644 --- a/loleaflet/src/layer/tile/CalcTileLayer.js +++ b/loleaflet/src/layer/tile/CalcTileLayer.js @@ -736,7 +736,7 @@ L.CalcTileLayer = L.CanvasTileLayer.extend({ updatecolumns: updateCols, cursor: this._getCursorPosSize(), selection: this._getSelectionHeaderData(), - converter: this._twipsToPixels, + converter: this._twipsToCorePixels, context: this }); }, @@ -1122,7 +1122,7 @@ L.CalcSplitPanesContext = L.SplitPanesContext.extend({ return this._splitCell.y; }, - // Calculates the split position in (core-pixels) from the split-cell. + // Calculates the split position in core-pixels from the split-cell. setSplitPosFromCell: function (forceSplittersUpdate) { var newSplitPos = this._docLayer.sheetGeometry.getCellRect(this._splitCell.x, this._splitCell.y).min; @@ -1585,6 +1585,7 @@ L.SheetDimension = L.Class.extend({ var posCorePx = 0; // position in core pixels. var dimensionObj = this; + var finalPosTwips = 0; this._visibleSizes.addCustomDataForEachSpan(function ( index, size, /* size in twips of one element in the span */ @@ -1592,12 +1593,14 @@ L.SheetDimension = L.Class.extend({ // Important: rounding needs to be done in core pixels to match core. var sizeCorePxOne = Math.floor(size / dimensionObj._twipsPerCorePixel); - posCorePx += (sizeCorePxOne * spanLength); + posCorePx += (sizeCorePxOne * spanLength); // Rounding errors (so the bugs) increase with every addition, we shouldn't use this variable. + finalPosTwips += size * spanLength; var customData = { sizecore: sizeCorePxOne, poscorepx: posCorePx, - posTwips: size * spanLength + posTwips: size * spanLength, + finalPosTwips: finalPosTwips }; return customData; @@ -1662,20 +1665,15 @@ L.SheetDimension = L.Class.extend({ return undefined; } - var numSizes = span.end - index + 1; - if (unitName === 'corepixels') { - return { - startpos: (span.data.poscorepx - span.data.sizecore * numSizes), - size: span.data.sizecore - }; - } - - if (unitName === 'twips') { - return { - startpos: (span.data.posTwips - span.size * numSizes), - size: span.size - }; - } + var numSizes = span.end - span.start + 1; + var offset = index - span.start; + var offsetTwips = offset * span.size; + var startTwips = span.data.finalPosTwips - span.size * numSizes; + var finalPosElementTwips = startTwips + offsetTwips; + return { + startpos: Math.floor(finalPosElementTwips / (unitName === 'corepixels' ? this._twipsPerCorePixel: 1)), + size: Math.round(span.size / (unitName === 'corepixels' ? this._twipsPerCorePixel: 1)) + }; }, forEachInRange: function (start, end, callback) { @@ -1692,20 +1690,24 @@ L.SheetDimension = L.Class.extend({ // callback with a position for each grid line in this pixel range forEachInCorePixelRange: function(startPix, endPix, callback) { + // Let's not use poscorepx variable. + var startTwips = startPix * this._twipsPerCorePixel; + var endTwips = endPix * this._twipsPerCorePixel; + this._visibleSizes.forEachSpan(function (spanData) { // do we overlap ? - var spanFirstCorePx = spanData.data.poscorepx - - (spanData.data.sizecore * (spanData.end - spanData.start + 1)); - if (spanFirstCorePx < endPix && spanData.data.poscorepx > startPix) + var firsSpanStartTwips = spanData.data.finalPosElementTwips - (spanData.size * (spanData.end - spanData.start + 1)); + + if (firsSpanStartTwips < endTwips && spanData.data.finalPosElementTwips > startTwips) { - var firstCorePx = Math.max( - spanFirstCorePx, - startPix + spanData.data.sizecore - - ((startPix - spanFirstCorePx) % spanData.data.sizecore)); - var lastCorePx = Math.min(endPix, spanData.data.poscorepx); - - for (var pos = firstCorePx; pos <= lastCorePx; pos += spanData.data.sizecore) { - callback(pos); + var firstCoreTwips = Math.max( + firsSpanStartTwips, + startTwips + spanData.size - + ((startTwips - firsSpanStartTwips) % spanData.size)); + var spanEndTwips = Math.min(endTwips, spanData.data.finalPosElementTwips); + + for (var pos = firstCoreTwips; pos <= spanEndTwips; pos += spanData.size) { + callback(pos / this._twipsPerCorePixel); } } }); @@ -1720,7 +1722,7 @@ L.SheetDimension = L.Class.extend({ // an object with this index and the span data. _getSpanAndIndexFromTwipsPos: function (pos) { var result = {}; - var span = this._visibleSizes.getSpanDataByCustomDataField(pos, 'posTwips'); + var span = this._visibleSizes.getSpanDataByFinalPosTwips(pos, 'finalPosTwips'); result.span = span; if (span === undefined) { // enforce limits. @@ -1729,7 +1731,7 @@ L.SheetDimension = L.Class.extend({ return result; } var elementCount = span.end - span.start + 1; - var posStart = (span.data.posTwips - span.size * elementCount); + var posStart = (span.data.finalPosTwips - span.size * elementCount); var sizeOne = span.size; // always round down as relativeIndex is zero-based. @@ -1952,13 +1954,13 @@ L.SpanList = L.Class.extend({ return this._getSpanData(spanid); }, - getSpanDataByCustomDataField: function (value, fieldName) { + getSpanDataByFinalPosTwips: function (value, fieldName) { - if (typeof value != 'number' || typeof fieldName != 'string' || !fieldName) { + if (typeof value !== 'number' || typeof fieldName !== 'string' || !fieldName) { return undefined; } - var spanid = this._searchByCustomDataField(value, fieldName); + var spanid = this._searchByFinalPosTwips(value, fieldName); if (spanid == -1) { return undefined; } @@ -2022,6 +2024,54 @@ L.SpanList = L.Class.extend({ }); }, + /// value should be number, values should be ordered by asc. + _searchByFinalPosTwips: function (value, fieldName) { + var startIndex = 0; + var endIndex = this._spanlist.length - 1; + var currentIndex; + var currentValue; + var spanid = -1; + while (startIndex <= endIndex) { + currentIndex = Math.floor((startIndex + endIndex) / 2); + currentValue = this._spanlist[currentIndex].data[fieldName]; + if (value <= currentValue) { + if (currentIndex > 0) { + if (value > this._spanlist[currentIndex - 1].data[fieldName]) { + spanid = currentIndex; + break; + } + else { + endIndex = currentIndex; + } + } + else { + spanid = currentIndex; + break; + } + } + else if (value > currentValue) { + startIndex = currentIndex + 1; + } + } + + // Now if we have a spanid, let's check if its pos is the same with the previous. If so, we will take the previous. + if (spanid !== -1 && spanid > 0) { + var go = true; + while (go === true) { + if (this._spanlist[spanid].data[fieldName] === this._spanlist[spanid - 1].data[fieldName]) + spanid--; + else + go = false; + + if (spanid === 0) + go = false; + } + } + + return spanid; + }, + + // TODO: To be removed. If another field other than finalPosTwips should be searched, "above" function may be generalized. _searchByCustomDataField: function (value, fieldName) { // All custom searchable data values are assumed to start @@ -2318,6 +2368,7 @@ L.DimensionOutlines = L.Class.extend({ } }); +//TODO: Remove (or solve the bug) below. It mis-calculates span. // Does binary search on array for key, possibly using a custom direction provider. // Of course, this assumes that the array is sorted (w.r.t to the semantics of diff --git a/loleaflet/src/layer/tile/CanvasTileLayer.js b/loleaflet/src/layer/tile/CanvasTileLayer.js index 7280fc94b7..ed0d1991bc 100644 --- a/loleaflet/src/layer/tile/CanvasTileLayer.js +++ b/loleaflet/src/layer/tile/CanvasTileLayer.js @@ -137,21 +137,17 @@ L.CanvasTilePainter = L.Class.extend({ var viewBounds = this._map.getPixelBoundsCore(); var splitPanesContext = this._layer.getSplitPanesContext(); - var paneBoundsList = splitPanesContext ? - splitPanesContext.getPxBoundList(viewBounds) : - [viewBounds]; + var paneBoundsList = splitPanesContext ? splitPanesContext.getPxBoundList(viewBounds) : [viewBounds]; var canvasCorePx = new L.Point(this._canvas.width, this._canvas.height); return { canvasSize: canvasCorePx, - tileSize: tileSize, - viewBounds: viewBounds, - paneBoundsList: paneBoundsList }; + tileSize: tileSize, + viewBounds: viewBounds, + paneBoundsList: paneBoundsList, + panesActive: splitPanesContext ? true: false}; }, - paint: function (tile, ctx) { - if (!ctx) - ctx = this._paintContext(); - + _paintWithPaneBounds: function (tile, ctx) { var tileTopLeft = tile.coords.getPos(); var tileBounds = new L.Bounds(tileTopLeft, tileTopLeft.add(ctx.tileSize)); @@ -201,6 +197,24 @@ L.CanvasTilePainter = L.Class.extend({ } }, + _paintSimple: function (tile, ctx) { + var offset = new L.Point(tile.coords.getPos().x - ctx.viewBounds.min.x, tile.coords.getPos().y - ctx.viewBounds.min.y); + this._canvasCtx.drawImage(tile.el, + offset.x, + offset.y, + ctx.tileSize.x, ctx.tileSize.y); + }, + + paint: function (tile, ctx) { + if (!ctx) + ctx = this._paintContext(); + + if (ctx.panesActive === false) + this._paintSimple(tile, ctx); + else + this._paintWithPaneBounds(tile, ctx); + }, + _drawSplits: function () { var splitPanesContext = this._layer.getSplitPanesContext(); if (!splitPanesContext) { @@ -336,8 +350,6 @@ L.CanvasTileLayer = L.TileLayer.extend({ } L.TileLayer.prototype._initContainer.call(this); - this.options.tileWidthTwips /= L.Util.getDpiScaleFactor(true); - this.options.tileHeightTwips /= L.Util.getDpiScaleFactor(true); var mapContainer = this._map.getContainer(); var canvasContainerClass = 'leaflet-canvas-container'; @@ -592,12 +604,24 @@ L.CanvasTileLayer = L.TileLayer.extend({ (twips.y / this._tileHeightTwips) * (this._tileSize / this._painter._dpiScale)); }, + _twipsToCorePixels: function (twips) { + return new L.Point( + (twips.x / this._tileWidthTwips) * this._tileSize, + (twips.y / this._tileHeightTwips) * this._tileSize); + }, + _cssPixelsToTwips: function (pixels) { return new L.Point( ((pixels.x * this._painter._dpiScale) / this._tileSize) * this._tileWidthTwips, ((pixels.y * this._painter._dpiScale) / this._tileSize) * this._tileHeightTwips); }, + _corePixelsToTwips: function (pixels) { + return new L.Point( + (pixels.x / this._tileSize) * this._tileWidthTwips, + (pixels.y / this._tileSize) * this._tileHeightTwips); + }, + _twipsToLatLng: function (twips, zoom) { var pixels = this._twipsToCssPixels(twips); return this._map.unproject(pixels, zoom); @@ -650,7 +674,7 @@ L.CanvasTileLayer = L.TileLayer.extend({ 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); + docPixelLimits = docPixelLimits.multiplyBy(this._tileSize / this._painter._dpiScale); var scale = this._map.getZoomScale(zoom, 10); var topLeft = new L.Point(0, 0); topLeft = this._map.unproject(topLeft.multiplyBy(scale)); @@ -670,7 +694,7 @@ L.CanvasTileLayer = L.TileLayer.extend({ var scrollPixelLimits = new L.Point(this._docWidthTwips / this._tileWidthTwips, this._docHeightTwips / this._tileHeightTwips); - scrollPixelLimits = scrollPixelLimits.multiplyBy(this._tileSize); + scrollPixelLimits = scrollPixelLimits.multiplyBy(this._tileSize / this._painter._dpiScale); if (extraSize) { // extraSize is unscaled. scrollPixelLimits = scrollPixelLimits.add(extraSize); |