public DocumentLocation PointToLocation (double xp, double yp, bool endAtEol = false, bool snapCharacters = false)
{
lineNumber = System.Math.Min (margin.YToLine (yp + margin.textEditor.VAdjustment.Value), margin.Document.LineCount);
line = lineNumber <= margin.Document.LineCount ? margin.Document.GetLine (lineNumber) : null;
this.snapCharacters = snapCharacters;
if (line == null)
return DocumentLocation.Empty;
int offset = line.Offset;
xp -= margin.TextStartPosition;
xp += margin.textEditor.HAdjustment.Value;
xp *= Pango.Scale.PangoScale;
if (xp < 0)
return new DocumentLocation (lineNumber, DocumentLocation.MinColumn);
yp = 0;
// yp -= margin.LineToY (lineNumber);
// yp *= Pango.Scale.PangoScale;
int column = DocumentLocation.MinColumn;
ISyntaxMode mode = margin.Document.SyntaxMode != null && margin.textEditor.Options.EnableSyntaxHighlighting ? margin.Document.SyntaxMode : new SyntaxMode (margin.Document);
IEnumerable<FoldSegment> foldings = margin.Document.GetStartFoldings (line);
bool done = false;
Pango.Layout measueLayout = null;
try {
restart:
int logicalRulerColumn = line.GetLogicalColumn (margin.textEditor.GetTextEditorData (), margin.textEditor.Options.RulerColumn);
foreach (FoldSegment folding in foldings.Where(f => f.IsFolded)) {
int foldOffset = folding.StartLine.Offset + folding.Column - 1;
if (foldOffset < offset)
continue;
layoutWrapper = margin.CreateLinePartLayout (mode, line, logicalRulerColumn, line.Offset, foldOffset - offset, -1, -1);
done |= ConsumeLayout ((int)(xp - xPos), (int)(yp - yPos));
if (done)
break;
int height, width;
layoutWrapper.Layout.GetPixelSize (out width, out height);
xPos += width * (int)Pango.Scale.PangoScale;
if (measueLayout == null) {
measueLayout = margin.textEditor.LayoutCache.RequestLayout ();
measueLayout.SetText (folding.Description);
measueLayout.FontDescription = margin.textEditor.Options.Font;
}
int delta;
measueLayout.GetPixelSize (out delta, out height);
delta *= (int)Pango.Scale.PangoScale;
xPos += delta;
if (xPos - delta / 2 >= xp) {
index = foldOffset - offset;
done = true;
break;
}
offset = folding.EndLine.Offset + folding.EndColumn - 1;
DocumentLocation foldingEndLocation = margin.Document.OffsetToLocation (offset);
lineNumber = foldingEndLocation.Line;
column = foldingEndLocation.Column;
if (xPos >= xp) {
index = 0;
done = true;
break;
}
if (folding.EndLine != line) {
line = folding.EndLine;
foldings = margin.Document.GetStartFoldings (line);
goto restart;
}
}
if (!done) {
layoutWrapper = margin.CreateLinePartLayout (mode, line, logicalRulerColumn, offset, line.Offset + line.Length - offset, -1, -1);
if (!ConsumeLayout ((int)(xp - xPos), (int)(yp - yPos))) {
if (endAtEol)
return DocumentLocation.Empty;
}
}
} finally {
if (measueLayout != null)
measueLayout.Dispose ();
}
return new DocumentLocation (lineNumber, column + index);
}
}