mirror of
https://github.com/atom/atom.git
synced 2026-02-09 14:15:24 -05:00
By clipping positions only in the TextEditorComponent, we can ensure that we check for the presence of a rendered line for the clipped row value.
55 lines
1.5 KiB
CoffeeScript
55 lines
1.5 KiB
CoffeeScript
{Point} = require 'text-buffer'
|
|
|
|
module.exports =
|
|
class FakeLinesYardstick
|
|
constructor: (@model) ->
|
|
@characterWidthsByScope = {}
|
|
|
|
getScopedCharacterWidth: (scopeNames, char) ->
|
|
@getScopedCharacterWidths(scopeNames)[char]
|
|
|
|
getScopedCharacterWidths: (scopeNames) ->
|
|
scope = @characterWidthsByScope
|
|
for scopeName in scopeNames
|
|
scope[scopeName] ?= {}
|
|
scope = scope[scopeName]
|
|
scope.characterWidths ?= {}
|
|
scope.characterWidths
|
|
|
|
setScopedCharacterWidth: (scopeNames, character, width) ->
|
|
@getScopedCharacterWidths(scopeNames)[character] = width
|
|
|
|
pixelPositionForScreenPosition: (screenPosition) ->
|
|
screenPosition = Point.fromObject(screenPosition)
|
|
|
|
targetRow = screenPosition.row
|
|
targetColumn = screenPosition.column
|
|
baseCharacterWidth = @model.getDefaultCharWidth()
|
|
|
|
top = targetRow * @model.getLineHeightInPixels()
|
|
left = 0
|
|
column = 0
|
|
|
|
iterator = @model.tokenizedLineForScreenRow(targetRow).getTokenIterator()
|
|
while iterator.next()
|
|
characterWidths = @getScopedCharacterWidths(iterator.getScopes())
|
|
|
|
valueIndex = 0
|
|
text = iterator.getText()
|
|
while valueIndex < text.length
|
|
if iterator.isPairedCharacter()
|
|
char = text
|
|
charLength = 2
|
|
valueIndex += 2
|
|
else
|
|
char = text[valueIndex]
|
|
charLength = 1
|
|
valueIndex++
|
|
|
|
break if column is targetColumn
|
|
|
|
left += characterWidths[char] ? baseCharacterWidth unless char is '\0'
|
|
column += charLength
|
|
|
|
{top, left}
|