   screenPositionForPixelPosition: (pixelPosition) ->
     targetTop = pixelPosition.top
     targetLeft = pixelPosition.left
-    defaultCharWidth = @model.getDefaultCharWidth()
     row = Math.floor(targetTop / @model.getLineHeightInPixels())
     targetLeft = 0 if row < 0
     targetLeft = Infinity if row > @model.getLastScreenRow()
     row = Math.min(row, @model.getLastScreenRow())
     row = Math.max(0, row)
 
-    line = @model.tokenizedLineForScreenRow(row)
-    lineNode = @lineNodesProvider.lineNodeForLineIdAndScreenRow(line?.id, row)
+    lineNode = @lineNodesProvider.lineNodeForScreenRow(row)
+    return Point(row, 0) unless lineNode
 
-    return Point(row, 0) unless lineNode? and line?
+    textNodes = @lineNodesProvider.textNodesForScreenRow(row)
+    lineOffset = lineNode.getBoundingClientRect().left
+    targetLeft += lineOffset
 
-    textNodes = @lineNodesProvider.textNodesForLineIdAndScreenRow(line.id, row)
-    column = 0
-    previousColumn = 0
-    previousLeft = 0
+    textNodeStartColumn = 0
+    for textNode in textNodes
+      {length: textNodeLength, textContent: textNodeContent} = textNode
+      textNodeRight = @clientRectForRange(textNode, 0, textNodeLength).right
 
-    @tokenIterator.reset(line, false)
-    while @tokenIterator.next()
-      text = @tokenIterator.getText()
-      textIndex = 0
-      while textIndex < text.length
-        if @tokenIterator.isPairedCharacter()
-          char = text
-          charLength = 2
-          textIndex += 2
-        else
-          char = text[textIndex]
-          charLength = 1
-          textIndex++
+      if textNodeRight > targetLeft
+        characterIndex = 0
+        while characterIndex < textNodeLength
+          if isPairedCharacter(textNodeContent, characterIndex)
+            nextCharacterIndex = characterIndex + 2
+          else
+            nextCharacterIndex = characterIndex + 1
 
-        unless textNode?
-          textNode = textNodes.shift()
-          textNodeLength = textNode.textContent.length
-          textNodeIndex = 0
-          nextTextNodeIndex = textNodeLength
+          rangeRect = @clientRectForRange(textNode, characterIndex, nextCharacterIndex)
 
-        while nextTextNodeIndex <= column
-          textNode = textNodes.shift()
-          textNodeLength = textNode.textContent.length
-          textNodeIndex = nextTextNodeIndex
-          nextTextNodeIndex = textNodeIndex + textNodeLength
+          if rangeRect.right > targetLeft
+            if targetLeft <= ((rangeRect.left + rangeRect.right) / 2)
+              return Point(row, textNodeStartColumn + characterIndex)
+            else
+              return Point(row, textNodeStartColumn + nextCharacterIndex)
+          else
+            characterIndex = nextCharacterIndex
 
-        indexWithinTextNode = column - textNodeIndex
-        left = @leftPixelPositionForCharInTextNode(lineNode, textNode, indexWithinTextNode)
-        charWidth = left - previousLeft
+      textNodeStartColumn += textNodeLength
 
-        return Point(row, previousColumn) if targetLeft <= previousLeft + (charWidth / 2)
-
-        previousLeft = left
-        previousColumn = column
-        column += charLength
-
-    if targetLeft <= previousLeft + (charWidth / 2)
-      Point(row, previousColumn)
-    else
-      Point(row, column)
+    Point(row, textNodeStartColumn)
 
   pixelPositionForScreenPosition: (screenPosition) ->
     targetRow = screenPosition.row

TokenIterator = require './token-iterator'
{Point} = require 'text-buffer'

module.exports =
class LinesYardstick

    else
      0

  clientRectForRange: (textNode, startIndex, endIndex) ->
    @rangeForMeasurement.setStart(textNode, startIndex)
    @rangeForMeasurement.setEnd(textNode, endIndex)
    @rangeForMeasurement.getBoundingClientRect()
