(x, y)
| 1804 | } |
| 1805 | // Coords must be lineSpace-local |
| 1806 | function coordsChar(x, y) { |
| 1807 | if (y < 0) y = 0; |
| 1808 | var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th); |
| 1809 | var lineNo = lineAtHeight(doc, heightPos); |
| 1810 | if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length}; |
| 1811 | var lineObj = getLine(lineNo), text = lineObj.text; |
| 1812 | var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0; |
| 1813 | if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0}; |
| 1814 | function getX(len) { |
| 1815 | var sp = measureLine(lineObj, len); |
| 1816 | if (tw) { |
| 1817 | var off = Math.round(sp.top / th); |
| 1818 | return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth); |
| 1819 | } |
| 1820 | return sp.left; |
| 1821 | } |
| 1822 | var from = 0, fromX = 0, to = text.length, toX; |
| 1823 | // Guess a suitable upper bound for our search. |
| 1824 | var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw)); |
| 1825 | for (;;) { |
| 1826 | var estX = getX(estimated); |
| 1827 | if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2)); |
| 1828 | else {toX = estX; to = estimated; break;} |
| 1829 | } |
| 1830 | if (x > toX) return {line: lineNo, ch: to}; |
| 1831 | // Try to guess a suitable lower bound as well. |
| 1832 | estimated = Math.floor(to * 0.8); estX = getX(estimated); |
| 1833 | if (estX < x) {from = estimated; fromX = estX;} |
| 1834 | // Do a binary search between these bounds. |
| 1835 | for (;;) { |
| 1836 | if (to - from <= 1) return {line: lineNo, ch: (toX - x > x - fromX) ? from : to}; |
| 1837 | var middle = Math.ceil((from + to) / 2), middleX = getX(middle); |
| 1838 | if (middleX > x) {to = middle; toX = middleX;} |
| 1839 | else {from = middle; fromX = middleX;} |
| 1840 | } |
| 1841 | } |
| 1842 | function pageCoords(pos) { |
| 1843 | var local = localCoords(pos, true), off = eltOffset(lineSpace); |
| 1844 | return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot}; |
no test coverage detected