| 1749 | // These are used to go from pixel positions to character |
| 1750 | // positions, taking varying character widths into account. |
| 1751 | function charFromX(line, x) { |
| 1752 | if (x <= 0) return 0; |
| 1753 | var lineObj = getLine(line), text = lineObj.text; |
| 1754 | function getX(len) { |
| 1755 | return measureLine(lineObj, len).left; |
| 1756 | } |
| 1757 | var from = 0, fromX = 0, to = text.length, toX; |
| 1758 | // Guess a suitable upper bound for our search. |
| 1759 | var estimated = Math.min(to, Math.ceil(x / charWidth())); |
| 1760 | for (;;) { |
| 1761 | var estX = getX(estimated); |
| 1762 | if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2)); |
| 1763 | else {toX = estX; to = estimated; break;} |
| 1764 | } |
| 1765 | if (x > toX) return to; |
| 1766 | // Try to guess a suitable lower bound as well. |
| 1767 | estimated = Math.floor(to * 0.8); estX = getX(estimated); |
| 1768 | if (estX < x) {from = estimated; fromX = estX;} |
| 1769 | // Do a binary search between these bounds. |
| 1770 | for (;;) { |
| 1771 | if (to - from <= 1) return (toX - x > x - fromX) ? from : to; |
| 1772 | var middle = Math.ceil((from + to) / 2), middleX = getX(middle); |
| 1773 | if (middleX > x) {to = middle; toX = middleX;} |
| 1774 | else {from = middle; fromX = middleX;} |
| 1775 | } |
| 1776 | } |
| 1777 | |
| 1778 | var tempId = "CodeMirror-temp-" + Math.floor(Math.random() * 0xffffff).toString(16); |
| 1779 | function measureLine(line, ch) { |