aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/ScintillaDoc.html10
-rw-r--r--include/Scintilla.h2
-rw-r--r--include/Scintilla.iface7
-rw-r--r--src/Editor.cxx106
-rw-r--r--src/Editor.h3
5 files changed, 62 insertions, 66 deletions
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html
index bf1f0bbb0..ab7cb5da0 100644
--- a/doc/ScintillaDoc.html
+++ b/doc/ScintillaDoc.html
@@ -1007,6 +1007,9 @@ struct TextToFind {
<a class="message" href="#SCI_POSITIONFROMPOINT">SCI_POSITIONFROMPOINT(int x, int y)</a><br />
<a class="message" href="#SCI_POSITIONFROMPOINTCLOSE">SCI_POSITIONFROMPOINTCLOSE(int x, int
y)</a><br />
+ <a class="message" href="#SCI_CHARPOSITIONFROMPOINT">SCI_CHARPOSITIONFROMPOINT(int x, int y)</a><br />
+ <a class="message" href="#SCI_CHARPOSITIONFROMPOINTCLOSE">SCI_CHARPOSITIONFROMPOINTCLOSE(int x, int
+ y)</a><br />
<a class="message" href="#SCI_POINTXFROMPOSITION">SCI_POINTXFROMPOSITION(&lt;unused&gt;, int
position)</a><br />
<a class="message" href="#SCI_POINTYFROMPOSITION">SCI_POINTYFROMPOSITION(&lt;unused&gt;, int
@@ -1343,6 +1346,13 @@ struct TextToFind {
<code>SCI_POSITIONFROMPOINTCLOSE</code> is similar but returns -1 if the point is outside the
window or not close to any characters.</p>
+ <p><b id="SCI_CHARPOSITIONFROMPOINT">SCI_CHARPOSITIONFROMPOINT(int x, int y)</b><br />
+ <b id="SCI_CHARPOSITIONFROMPOINTCLOSE">SCI_CHARPOSITIONFROMPOINTCLOSE(int x, int y)</b><br />
+ <code>SCI_CHARPOSITIONFROMPOINT</code> finds the closest character to a point and
+ <code>SCI_CHARPOSITIONFROMPOINTCLOSE</code> is similar but returns -1 if the point is outside the
+ window or not close to any characters. This is similar to the previous methods but finds characters rather than
+ inter-character positions.</p>
+
<p><b id="SCI_POINTXFROMPOSITION">SCI_POINTXFROMPOSITION(&lt;unused&gt;, int pos)</b><br />
<b id="SCI_POINTYFROMPOSITION">SCI_POINTYFROMPOSITION(&lt;unused&gt;, int pos)</b><br />
These messages return the x and y display pixel location of text at position <code>pos</code>
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 677cd0325..b31e81831 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -705,6 +705,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_ANNOTATIONGETSTYLEOFFSET 2551
#define UNDO_MAY_COALESCE 1
#define SCI_ADDUNDOACTION 2560
+#define SCI_CHARPOSITIONFROMPOINT 2561
+#define SCI_CHARPOSITIONFROMPOINTCLOSE 2562
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index a2c905fb7..9c9eeb1be 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -1907,6 +1907,13 @@ val UNDO_MAY_COALESCE=1
# Add a container action to the undo stack
fun void AddUndoAction=2560(int token, int flags)
+# Find the position of a character from a point within the window.
+fun position CharPositionFromPoint=2561(int x, int y)
+
+# Find the position of a character from a point within the window.
+# Return INVALID_POSITION if not close to text.
+fun position CharPositionFromPointClose=2562(int x, int y)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
diff --git a/src/Editor.cxx b/src/Editor.cxx
index aa6f0d52e..0ec0b9160 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -480,20 +480,31 @@ void Editor::SetTopLine(int topLineNew) {
posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
}
-int Editor::PositionFromLocation(Point pt) {
+int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) {
RefreshStyleData();
+ if (canReturnInvalid) {
+ PRectangle rcClient = GetTextRectangle();
+ if (!rcClient.Contains(pt))
+ return INVALID_POSITION;
+ if (pt.x < vs.fixedColumnWidth)
+ return INVALID_POSITION;
+ if (pt.y < 0)
+ return INVALID_POSITION;
+ }
pt.x = pt.x - vs.fixedColumnWidth + xOffset;
int visibleLine = pt.y / vs.lineHeight + topLine;
if (pt.y < 0) { // Division rounds towards 0
visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
}
- if (visibleLine < 0)
+ if (!canReturnInvalid && (visibleLine < 0))
visibleLine = 0;
int lineDoc = cs.DocFromDisplay(visibleLine);
+ if (canReturnInvalid && (lineDoc < 0))
+ return INVALID_POSITION;
if (lineDoc >= pdoc->LinesTotal())
- return pdoc->Length();
+ return canReturnInvalid ? INVALID_POSITION : pdoc->Length();
unsigned int posLineStart = pdoc->LineStart(lineDoc);
- int retVal = posLineStart;
+ int retVal = canReturnInvalid ? INVALID_POSITION : posLineStart;
AutoSurface surface(this);
AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
if (surface && ll) {
@@ -511,68 +522,29 @@ int Editor::PositionFromLocation(Point pt) {
}
int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);
while (i < lineEnd) {
- if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
- return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+ if (charPosition) {
+ if ((pt.x + subLineStart) < (ll->positions[i + 1])) {
+ return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+ }
+ } else {
+ if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
+ return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+ }
}
i++;
}
- return lineEnd + posLineStart;
- }
- retVal = ll->numCharsInLine + posLineStart;
- }
- return retVal;
-}
-
-// Like PositionFromLocation but INVALID_POSITION returned when not near any text.
-int Editor::PositionFromLocationClose(Point pt) {
- RefreshStyleData();
- PRectangle rcClient = GetTextRectangle();
- if (!rcClient.Contains(pt))
- return INVALID_POSITION;
- if (pt.x < vs.fixedColumnWidth)
- return INVALID_POSITION;
- if (pt.y < 0)
- return INVALID_POSITION;
- pt.x = pt.x - vs.fixedColumnWidth + xOffset;
- int visibleLine = pt.y / vs.lineHeight + topLine;
- if (pt.y < 0) { // Division rounds towards 0
- visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
- }
- int lineDoc = cs.DocFromDisplay(visibleLine);
- if (lineDoc < 0)
- return INVALID_POSITION;
- if (lineDoc >= pdoc->LinesTotal())
- return INVALID_POSITION;
- AutoSurface surface(this);
- AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
- if (surface && ll) {
- LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
- unsigned int posLineStart = pdoc->LineStart(lineDoc);
- int lineStartSet = cs.DisplayFromDoc(lineDoc);
- int subLine = visibleLine - lineStartSet;
- if (subLine < ll->lines) {
- int lineStart = ll->LineStart(subLine);
- int lineEnd = ll->LineLastVisible(subLine);
- int subLineStart = ll->positions[lineStart];
-
- if (actualWrapVisualStartIndent != 0) {
- if (lineStart != 0) // Wrapped
- pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth;
- }
- int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);
- while (i < lineEnd) {
- if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
- return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+ if (canReturnInvalid) {
+ if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
+ return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1);
}
- i++;
- }
- if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
- return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1);
+ } else {
+ return lineEnd + posLineStart;
}
}
+ if (!canReturnInvalid)
+ return ll->numCharsInLine + posLineStart;
}
-
- return INVALID_POSITION;
+ return retVal;
}
/**
@@ -3847,7 +3819,7 @@ void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) {
SCNotification scn = {0};
scn.nmhdr.code = SCN_DOUBLECLICK;
scn.line = LineFromLocation(pt);
- scn.position = PositionFromLocationClose(pt);
+ scn.position = PositionFromLocation(pt, true);
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0);
NotifyParent(scn);
@@ -3928,7 +3900,7 @@ void Editor::NotifyNeedShown(int pos, int len) {
void Editor::NotifyDwelling(Point pt, bool state) {
SCNotification scn = {0};
scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND;
- scn.position = PositionFromLocationClose(pt);
+ scn.position = PositionFromLocation(pt, true);
scn.x = pt.x;
scn.y = pt.y;
NotifyParent(scn);
@@ -5511,7 +5483,7 @@ bool Editor::PositionIsHotspot(int position) {
}
bool Editor::PointIsHotspot(Point pt) {
- int pos = PositionFromLocationClose(pt);
+ int pos = PositionFromLocation(pt, true);
if (pos == INVALID_POSITION)
return false;
return PositionIsHotspot(pos);
@@ -6679,10 +6651,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
break;
case SCI_POSITIONFROMPOINT:
- return PositionFromLocation(Point(wParam, lParam));
+ return PositionFromLocation(Point(wParam, lParam), false, false);
case SCI_POSITIONFROMPOINTCLOSE:
- return PositionFromLocationClose(Point(wParam, lParam));
+ return PositionFromLocation(Point(wParam, lParam), true, false);
+
+ case SCI_CHARPOSITIONFROMPOINT:
+ return PositionFromLocation(Point(wParam, lParam), false, true);
+
+ case SCI_CHARPOSITIONFROMPOINTCLOSE:
+ return PositionFromLocation(Point(wParam, lParam), true, true);
case SCI_GOTOLINE:
GoToLine(wParam);
diff --git a/src/Editor.h b/src/Editor.h
index 3b15920ff..d37606d5a 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -260,8 +260,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int MaxScrollPos();
Point LocationFromPosition(int pos);
int XFromPosition(int pos);
- int PositionFromLocation(Point pt);
- int PositionFromLocationClose(Point pt);
+ int PositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false);
int PositionFromLineX(int line, int x);
int LineFromLocation(Point pt);
void SetTopLine(int topLineNew);