Use an updated version of LineTopIndex

This commit is contained in:
Antonio Scandurra
2015-12-14 15:04:54 +01:00
parent c578f221bf
commit cfb30c795d
9 changed files with 56 additions and 258 deletions

View File

@@ -31,7 +31,7 @@ class FakeLinesYardstick
targetColumn = screenPosition.column
baseCharacterWidth = @model.getDefaultCharWidth()
top = @lineTopIndex.bottomPixelPositionForRow(targetRow)
top = @lineTopIndex.pixelPositionForRow(targetRow)
left = 0
column = 0
@@ -61,14 +61,14 @@ class FakeLinesYardstick
{top, left}
pixelRectForScreenRange: (screenRange) ->
top = @lineTopIndex.pixelPositionForRow(screenRange.start.row)
if screenRange.end.row > screenRange.start.row
top = @pixelPositionForScreenPosition(screenRange.start).top
left = 0
height = @lineTopIndex.topPixelPositionForRow(screenRange.end.row + 1) - top
height = @lineTopIndex.pixelPositionForRow(screenRange.end.row) - top + @model.getLineHeightInPixels()
width = @presenter.getScrollWidth()
else
{top, left} = @pixelPositionForScreenPosition(screenRange.start, false)
height = @lineTopIndex.topPixelPositionForRow(screenRange.end.row + 1) - top
{left} = @pixelPositionForScreenPosition(screenRange.start, false)
height = @lineTopIndex.pixelPositionForRow(screenRange.end.row) - top + @model.getLineHeightInPixels()
width = @pixelPositionForScreenPosition(screenRange.end, false).left - left
{top, left, width, height}

View File

@@ -1,189 +0,0 @@
/** @babel */
const LineTopIndex = require('../src/linear-line-top-index')
describe("LineTopIndex", function () {
let lineTopIndex
beforeEach(function () {
lineTopIndex = new LineTopIndex()
lineTopIndex.setDefaultLineHeight(10)
lineTopIndex.setMaxRow(12)
})
describe("::topPixelPositionForRow(row)", function () {
it("performs the simple math when there are no block decorations", function () {
expect(lineTopIndex.topPixelPositionForRow(0)).toBe(0)
expect(lineTopIndex.topPixelPositionForRow(4)).toBe(40)
expect(lineTopIndex.topPixelPositionForRow(5)).toBe(50)
expect(lineTopIndex.topPixelPositionForRow(12)).toBe(120)
expect(lineTopIndex.topPixelPositionForRow(13)).toBe(120)
expect(lineTopIndex.topPixelPositionForRow(14)).toBe(120)
lineTopIndex.splice(0, 2, 3)
expect(lineTopIndex.topPixelPositionForRow(0)).toBe(0)
expect(lineTopIndex.topPixelPositionForRow(4)).toBe(40)
expect(lineTopIndex.topPixelPositionForRow(5)).toBe(50)
expect(lineTopIndex.topPixelPositionForRow(12)).toBe(120)
expect(lineTopIndex.topPixelPositionForRow(13)).toBe(130)
expect(lineTopIndex.topPixelPositionForRow(14)).toBe(130)
})
it("takes into account inserted and removed blocks", function () {
let block1 = lineTopIndex.insertBlock(0, 10)
let block2 = lineTopIndex.insertBlock(3, 20)
let block3 = lineTopIndex.insertBlock(5, 20)
expect(lineTopIndex.topPixelPositionForRow(0)).toBe(0)
expect(lineTopIndex.topPixelPositionForRow(1)).toBe(20)
expect(lineTopIndex.topPixelPositionForRow(2)).toBe(30)
expect(lineTopIndex.topPixelPositionForRow(3)).toBe(40)
expect(lineTopIndex.topPixelPositionForRow(4)).toBe(70)
expect(lineTopIndex.topPixelPositionForRow(5)).toBe(80)
expect(lineTopIndex.topPixelPositionForRow(6)).toBe(110)
lineTopIndex.removeBlock(block1)
lineTopIndex.removeBlock(block3)
expect(lineTopIndex.topPixelPositionForRow(0)).toBe(0)
expect(lineTopIndex.topPixelPositionForRow(1)).toBe(10)
expect(lineTopIndex.topPixelPositionForRow(2)).toBe(20)
expect(lineTopIndex.topPixelPositionForRow(3)).toBe(30)
expect(lineTopIndex.topPixelPositionForRow(4)).toBe(60)
expect(lineTopIndex.topPixelPositionForRow(5)).toBe(70)
expect(lineTopIndex.topPixelPositionForRow(6)).toBe(80)
})
it("moves blocks down/up when splicing regions", function () {
let block1 = lineTopIndex.insertBlock(3, 20)
let block2 = lineTopIndex.insertBlock(5, 30)
lineTopIndex.splice(0, 0, 4)
expect(lineTopIndex.topPixelPositionForRow(0)).toBe(0)
expect(lineTopIndex.topPixelPositionForRow(6)).toBe(60)
expect(lineTopIndex.topPixelPositionForRow(7)).toBe(70)
expect(lineTopIndex.topPixelPositionForRow(8)).toBe(100)
expect(lineTopIndex.topPixelPositionForRow(9)).toBe(110)
expect(lineTopIndex.topPixelPositionForRow(10)).toBe(150)
expect(lineTopIndex.topPixelPositionForRow(11)).toBe(160)
lineTopIndex.splice(0, 6, 2)
expect(lineTopIndex.topPixelPositionForRow(0)).toBe(0)
expect(lineTopIndex.topPixelPositionForRow(3)).toBe(30)
expect(lineTopIndex.topPixelPositionForRow(4)).toBe(60)
expect(lineTopIndex.topPixelPositionForRow(5)).toBe(70)
expect(lineTopIndex.topPixelPositionForRow(6)).toBe(110)
lineTopIndex.splice(2, 4, 0)
expect(lineTopIndex.topPixelPositionForRow(0)).toBe(0)
expect(lineTopIndex.topPixelPositionForRow(1)).toBe(10)
expect(lineTopIndex.topPixelPositionForRow(2)).toBe(20)
expect(lineTopIndex.topPixelPositionForRow(3)).toBe(80)
expect(lineTopIndex.topPixelPositionForRow(4)).toBe(90)
expect(lineTopIndex.topPixelPositionForRow(5)).toBe(100)
expect(lineTopIndex.topPixelPositionForRow(6)).toBe(110)
expect(lineTopIndex.topPixelPositionForRow(7)).toBe(120)
expect(lineTopIndex.topPixelPositionForRow(8)).toBe(130)
expect(lineTopIndex.topPixelPositionForRow(9)).toBe(130)
})
})
describe("::rowForTopPixelPosition(top)", function () {
it("performs the simple math when there are no block decorations", function () {
expect(lineTopIndex.rowForTopPixelPosition(0)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(40)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(44)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(46)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(50)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(120)).toBe(12)
expect(lineTopIndex.rowForTopPixelPosition(130)).toBe(12)
expect(lineTopIndex.rowForTopPixelPosition(140)).toBe(12)
expect(lineTopIndex.rowForTopPixelPosition(145)).toBe(12)
lineTopIndex.splice(0, 2, 3)
expect(lineTopIndex.rowForTopPixelPosition(0)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(40)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(50)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(120)).toBe(12)
expect(lineTopIndex.rowForTopPixelPosition(130)).toBe(13)
expect(lineTopIndex.rowForTopPixelPosition(140)).toBe(13)
})
it("takes into account inserted and removed blocks", function () {
let block1 = lineTopIndex.insertBlock(0, 10)
let block2 = lineTopIndex.insertBlock(3, 20)
let block3 = lineTopIndex.insertBlock(5, 20)
expect(lineTopIndex.rowForTopPixelPosition(0)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(6)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(10)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(12)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(17)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(20)).toBe(1)
expect(lineTopIndex.rowForTopPixelPosition(30)).toBe(2)
expect(lineTopIndex.rowForTopPixelPosition(40)).toBe(3)
expect(lineTopIndex.rowForTopPixelPosition(70)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(80)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(90)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(95)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(106)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(110)).toBe(6)
expect(lineTopIndex.rowForTopPixelPosition(160)).toBe(11)
expect(lineTopIndex.rowForTopPixelPosition(166)).toBe(11)
expect(lineTopIndex.rowForTopPixelPosition(170)).toBe(12)
expect(lineTopIndex.rowForTopPixelPosition(240)).toBe(12)
lineTopIndex.removeBlock(block1)
lineTopIndex.removeBlock(block3)
expect(lineTopIndex.rowForTopPixelPosition(0)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(10)).toBe(1)
expect(lineTopIndex.rowForTopPixelPosition(20)).toBe(2)
expect(lineTopIndex.rowForTopPixelPosition(30)).toBe(3)
expect(lineTopIndex.rowForTopPixelPosition(60)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(70)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(80)).toBe(6)
})
it("moves blocks down/up when splicing regions", function () {
let block1 = lineTopIndex.insertBlock(3, 20)
let block2 = lineTopIndex.insertBlock(5, 30)
lineTopIndex.splice(0, 0, 4)
expect(lineTopIndex.rowForTopPixelPosition(0)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(60)).toBe(6)
expect(lineTopIndex.rowForTopPixelPosition(70)).toBe(7)
expect(lineTopIndex.rowForTopPixelPosition(100)).toBe(8)
expect(lineTopIndex.rowForTopPixelPosition(110)).toBe(9)
expect(lineTopIndex.rowForTopPixelPosition(150)).toBe(10)
expect(lineTopIndex.rowForTopPixelPosition(160)).toBe(11)
lineTopIndex.splice(0, 6, 2)
expect(lineTopIndex.rowForTopPixelPosition(0)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(30)).toBe(3)
expect(lineTopIndex.rowForTopPixelPosition(60)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(70)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(110)).toBe(6)
lineTopIndex.splice(2, 4, 0)
expect(lineTopIndex.rowForTopPixelPosition(0)).toBe(0)
expect(lineTopIndex.rowForTopPixelPosition(10)).toBe(1)
expect(lineTopIndex.rowForTopPixelPosition(20)).toBe(2)
expect(lineTopIndex.rowForTopPixelPosition(80)).toBe(3)
expect(lineTopIndex.rowForTopPixelPosition(90)).toBe(4)
expect(lineTopIndex.rowForTopPixelPosition(100)).toBe(5)
expect(lineTopIndex.rowForTopPixelPosition(110)).toBe(6)
expect(lineTopIndex.rowForTopPixelPosition(120)).toBe(7)
expect(lineTopIndex.rowForTopPixelPosition(130)).toBe(8)
expect(lineTopIndex.rowForTopPixelPosition(130)).toBe(8)
})
})
})

View File

@@ -57,9 +57,10 @@ describe "LinesYardstick", ->
textNodes
editor.setLineHeightInPixels(14)
lineTopIndex = new LineTopIndex()
lineTopIndex.setDefaultLineHeight(editor.getLineHeightInPixels())
lineTopIndex.setMaxRow(editor.getScreenLineCount())
lineTopIndex = new LineTopIndex({
maxRow: editor.getScreenLineCount(),
defaultLineHeight: editor.getLineHeightInPixels()
})
linesYardstick = new LinesYardstick(editor, mockPresenter, mockLineNodesProvider, lineTopIndex, atom.grammars)
afterEach ->

View File

@@ -27,7 +27,10 @@ describe "TextEditorPresenter", ->
buffer.destroy()
buildPresenterWithoutMeasurements = (params={}) ->
lineTopIndex = new LineTopIndex
lineTopIndex = new LineTopIndex({
maxRow: editor.getScreenLineCount(),
defaultLineHeight: editor.getLineHeightInPixels()
})
_.defaults params,
model: editor
config: atom.config
@@ -526,8 +529,6 @@ describe "TextEditorPresenter", ->
presenter = buildPresenter(scrollTop: 0, lineHeight: 10)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10
# Setting `null` as the DOM element, as it doesn't really matter here.
# Maybe a signal that we should separate models from views?
blockDecoration1 = editor.addBlockDecorationForScreenRow(0, null)
blockDecoration2 = editor.addBlockDecorationForScreenRow(3, null)
blockDecoration3 = editor.addBlockDecorationForScreenRow(7, null)
@@ -719,8 +720,6 @@ describe "TextEditorPresenter", ->
presenter = buildPresenter(scrollTop: 0, lineHeight: 10)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10
# Setting `null` as the DOM element, as it doesn't really matter here.
# Maybe a signal that we should separate models from views?
blockDecoration1 = editor.addBlockDecorationForScreenRow(0, null)
blockDecoration2 = editor.addBlockDecorationForScreenRow(3, null)
blockDecoration3 = editor.addBlockDecorationForScreenRow(7, null)
@@ -3041,8 +3040,8 @@ describe "TextEditorPresenter", ->
presenter.setBlockDecorationDimensions(blockDecoration3, 0, 7)
decorationState = getContentForGutterWithName(presenter, 'test-gutter')
expect(decorationState[decoration1.id].top).toBe lineHeight * marker1.getScreenRange().start.row
expect(decorationState[decoration1.id].height).toBe lineHeight * marker1.getScreenRange().getRowCount() + 3
expect(decorationState[decoration1.id].top).toBe lineHeight * marker1.getScreenRange().start.row + 3
expect(decorationState[decoration1.id].height).toBe lineHeight * marker1.getScreenRange().getRowCount()
expect(decorationState[decoration1.id].item).toBe decorationItem
expect(decorationState[decoration1.id].class).toBe 'test-class'
expect(decorationState[decoration2.id].top).toBe lineHeight * marker2.getScreenRange().start.row + 3 + 5
@@ -3286,8 +3285,6 @@ describe "TextEditorPresenter", ->
presenter = buildPresenter(scrollTop: 0, lineHeight: 10)
expect(presenter.getState().verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10
# Setting `null` as the DOM element, as it doesn't really matter here.
# Maybe a signal that we should separate models from views?
blockDecoration1 = editor.addBlockDecorationForScreenRow(0, null)
blockDecoration2 = editor.addBlockDecorationForScreenRow(3, null)
blockDecoration3 = editor.addBlockDecorationForScreenRow(7, null)

View File

@@ -31,9 +31,6 @@ class BlockDecorationsPresenter {
}
observeModel () {
this.lineTopIndex.setMaxRow(this.model.getScreenLineCount())
this.lineTopIndex.setDefaultLineHeight(this.model.getLineHeightInPixels())
this.disposables.add(this.model.onDidAddDecoration(this.observeDecoration.bind(this)))
this.disposables.add(this.model.onDidChange((changeEvent) => {
let oldExtent = changeEvent.end - changeEvent.start
@@ -54,11 +51,10 @@ class BlockDecorationsPresenter {
setDimensionsForDecoration (decoration, width, height) {
let block = this.blocksByDecoration.get(decoration)
if (block) {
this.lineTopIndex.resizeBlock(block, height)
this.lineTopIndex.resizeBlock(decoration.getMarker().id, height)
} else {
this.observeDecoration(decoration)
block = this.blocksByDecoration.get(decoration)
this.lineTopIndex.resizeBlock(block, height)
this.lineTopIndex.resizeBlock(decoration.getMarker().id, height)
}
this.measuredDecorations.add(decoration)
@@ -124,9 +120,9 @@ class BlockDecorationsPresenter {
didAddDecoration (decoration) {
let screenRow = decoration.getMarker().getHeadScreenPosition().row
let block = this.lineTopIndex.insertBlock(screenRow, 0)
this.decorationsByBlock.set(block, decoration)
this.blocksByDecoration.set(decoration, block)
this.lineTopIndex.insertBlock(decoration.getMarker().id, screenRow, 0)
this.decorationsByBlock.set(decoration.getMarker().id, decoration)
this.blocksByDecoration.set(decoration, decoration.getMarker().id)
this.emitter.emit('did-update-state')
}
@@ -136,16 +132,15 @@ class BlockDecorationsPresenter {
return
}
let block = this.blocksByDecoration.get(decoration)
let newScreenRow = decoration.getMarker().getHeadScreenPosition().row
this.lineTopIndex.moveBlock(block, newScreenRow)
this.lineTopIndex.moveBlock(decoration.getMarker().id, newScreenRow)
this.emitter.emit('did-update-state')
}
didDestroyDecoration (decoration) {
let block = this.blocksByDecoration.get(decoration)
if (block) {
this.lineTopIndex.removeBlock(block)
this.lineTopIndex.removeBlock(decoration.getMarker().id)
this.blocksByDecoration.delete(decoration)
this.decorationsByBlock.delete(block)
}

View File

@@ -1,27 +1,23 @@
'use strict'
"use babel"
module.exports =
class LineTopIndex {
constructor () {
this.idCounter = 1
export default class LineTopIndex {
constructor (params = {}) {
this.blocks = []
this.maxRow = 0
this.defaultLineHeight = 0
this.maxRow = params.maxRow || 0
this.setDefaultLineHeight(params.defaultLineHeight || 0)
}
setDefaultLineHeight (lineHeight) {
this.defaultLineHeight = lineHeight
}
setMaxRow (maxRow) {
this.maxRow = maxRow
getMaxRow () {
return this.maxRow
}
insertBlock (row, height) {
let id = this.idCounter++
insertBlock (id, row, height) {
this.blocks.push({id, row, height})
this.blocks.sort((a, b) => a.row - b.row)
return id
}
resizeBlock (id, height) {
@@ -62,26 +58,21 @@ class LineTopIndex {
block.row += newExtent - oldExtent
} else {
block.row = startRow + newExtent
// invalidate marker?
}
}
})
this.setMaxRow(this.maxRow + newExtent - oldExtent)
this.maxRow = this.maxRow + newExtent - oldExtent
}
topPixelPositionForRow (row) {
pixelPositionForRow (row) {
row = Math.min(row, this.maxRow)
let linesHeight = row * this.defaultLineHeight
let blocksHeight = this.blocks.filter((block) => block.row < row).reduce((a, b) => a + b.height, 0)
let blocksHeight = this.blocks.filter((block) => block.row <= row).reduce((a, b) => a + b.height, 0)
return linesHeight + blocksHeight
}
bottomPixelPositionForRow (row) {
return this.topPixelPositionForRow(row + 1) - this.defaultLineHeight
}
rowForTopPixelPosition (top, strategy) {
rowForPixelPosition (top, strategy) {
const roundingStrategy = strategy || 'floor'
let blocksHeight = 0
let lastRow = 0

View File

@@ -22,7 +22,7 @@ class LinesYardstick
targetTop = pixelPosition.top
targetLeft = pixelPosition.left
defaultCharWidth = @model.getDefaultCharWidth()
row = @lineTopIndex.rowForTopPixelPosition(targetTop, 'floor')
row = @lineTopIndex.rowForPixelPosition(targetTop, 'floor')
targetLeft = 0 if targetTop < 0
targetLeft = Infinity if row > @model.getLastScreenRow()
row = Math.min(row, @model.getLastScreenRow())
@@ -91,7 +91,7 @@ class LinesYardstick
@prepareScreenRowsForMeasurement([targetRow]) unless measureVisibleLinesOnly
top = @lineTopIndex.bottomPixelPositionForRow(targetRow)
top = @lineTopIndex.pixelPositionForRow(targetRow)
left = @leftPixelPositionForScreenPosition(targetRow, targetColumn)
@clearScreenRowsForMeasurement() unless measureVisibleLinesOnly
@@ -174,14 +174,14 @@ class LinesYardstick
left + width - offset
pixelRectForScreenRange: (screenRange, measureVisibleLinesOnly) ->
top = @lineTopIndex.pixelPositionForRow(screenRange.start.row)
if screenRange.end.row > screenRange.start.row
top = @pixelPositionForScreenPosition(screenRange.start, true, measureVisibleLinesOnly).top
left = 0
height = @lineTopIndex.topPixelPositionForRow(screenRange.end.row + 1) - top
height = @lineTopIndex.pixelPositionForRow(screenRange.end.row) - top + @model.getLineHeightInPixels()
width = @presenter.getScrollWidth()
else
{top, left} = @pixelPositionForScreenPosition(screenRange.start, false, measureVisibleLinesOnly)
height = @lineTopIndex.topPixelPositionForRow(screenRange.end.row + 1) - top
{left} = @pixelPositionForScreenPosition(screenRange.start, false, measureVisibleLinesOnly)
height = @lineTopIndex.pixelPositionForRow(screenRange.end.row) - top + @model.getLineHeightInPixels()
width = @pixelPositionForScreenPosition(screenRange.end, false, measureVisibleLinesOnly).left - left
{top, left, width, height}

View File

@@ -50,7 +50,10 @@ class TextEditorComponent
@observeConfig()
@setScrollSensitivity(@config.get('editor.scrollSensitivity'))
lineTopIndex = new LineTopIndex(@editor)
lineTopIndex = new LineTopIndex({
maxRow: @editor.getScreenLineCount(),
defaultLineHeight: @editor.getLineHeightInPixels()
})
@presenter = new TextEditorPresenter
model: @editor
tileSize: tileSize

View File

@@ -442,8 +442,8 @@ class TextEditorPresenter
continue if rowsWithinTile.length is 0
top = Math.round(@lineTopIndex.topPixelPositionForRow(tileStartRow))
bottom = Math.round(@lineTopIndex.topPixelPositionForRow(tileEndRow))
top = Math.round(@lineTopIndex.pixelPositionForRow(tileStartRow - 1) + @lineHeight)
bottom = Math.round(@lineTopIndex.pixelPositionForRow(tileEndRow - 1) + @lineHeight)
height = bottom - top
tile = @state.content.tiles[tileStartRow] ?= {}
@@ -659,8 +659,8 @@ class TextEditorPresenter
continue unless @gutterIsVisible(gutter)
for decorationId, {properties, screenRange} of @customGutterDecorationsByGutterName[gutterName]
top = @lineTopIndex.topPixelPositionForRow(screenRange.start.row)
bottom = @lineTopIndex.topPixelPositionForRow(screenRange.end.row + 1)
top = @lineTopIndex.pixelPositionForRow(screenRange.start.row)
bottom = @lineTopIndex.pixelPositionForRow(screenRange.end.row) + @lineHeight
@customGutterDecorations[gutterName][decorationId] =
top: top
height: bottom - top
@@ -724,12 +724,12 @@ class TextEditorPresenter
updateStartRow: ->
return unless @scrollTop? and @lineHeight?
@startRow = Math.max(0, @lineTopIndex.rowForTopPixelPosition(@scrollTop, "floor"))
@startRow = Math.max(0, @lineTopIndex.rowForPixelPosition(@scrollTop, "floor"))
updateEndRow: ->
return unless @scrollTop? and @lineHeight? and @height?
@endRow = @lineTopIndex.rowForTopPixelPosition(@scrollTop + @height + @lineHeight, 'ceil')
@endRow = @lineTopIndex.rowForPixelPosition(@scrollTop + @height + @lineHeight, 'ceil')
updateRowsPerPage: ->
rowsPerPage = Math.floor(@getClientHeight() / @lineHeight)
@@ -761,7 +761,7 @@ class TextEditorPresenter
updateVerticalDimensions: ->
if @lineHeight?
oldContentHeight = @contentHeight
@contentHeight = Math.round(@lineTopIndex.topPixelPositionForRow(Infinity))
@contentHeight = Math.round(@lineTopIndex.pixelPositionForRow(Infinity))
if @contentHeight isnt oldContentHeight
@updateHeight()
@@ -1340,7 +1340,7 @@ class TextEditorPresenter
screenRange.end.column = 0
repositionRegionWithinTile: (region, tileStartRow) ->
region.top += @scrollTop - @lineTopIndex.topPixelPositionForRow(tileStartRow)
region.top += @scrollTop - (@lineTopIndex.pixelPositionForRow(tileStartRow - 1) + @lineHeight)
region.left += @scrollLeft
buildHighlightRegions: (screenRange) ->
@@ -1495,7 +1495,7 @@ class TextEditorPresenter
@emitDidUpdateState()
didChangeFirstVisibleScreenRow: (screenRow) ->
@updateScrollTop(@lineTopIndex.topPixelPositionForRow(screenRow))
@updateScrollTop(@lineTopIndex.pixelPositionForRow(screenRow))
getVerticalScrollMarginInPixels: ->
Math.round(@model.getVerticalScrollMargin() * @lineHeight)
@@ -1516,8 +1516,8 @@ class TextEditorPresenter
verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels()
top = @lineTopIndex.bottomPixelPositionForRow(screenRange.start.row)
bottom = @lineTopIndex.bottomPixelPositionForRow(screenRange.end.row + 1)
top = @lineTopIndex.pixelPositionForRow(screenRange.start.row)
bottom = @lineTopIndex.pixelPositionForRow(screenRange.end.row) + @lineHeight
if options?.center
desiredScrollCenter = (top + bottom) / 2
@@ -1589,7 +1589,7 @@ class TextEditorPresenter
restoreScrollTopIfNeeded: ->
unless @scrollTop?
@updateScrollTop(@lineTopIndex.topPixelPositionForRow(@model.getFirstVisibleScreenRow()))
@updateScrollTop(@lineTopIndex.pixelPositionForRow(@model.getFirstVisibleScreenRow()))
restoreScrollLeftIfNeeded: ->
unless @scrollLeft?