Exemplo n.º 1
0
        public TextHitTestResult HitTestPoint(Point point)
        {
            float y = (float)point.Y;

            AvaloniaFormattedTextLine line = default;

            float nextTop = 0;

            foreach (var currentLine in _skiaLines)
            {
                if (currentLine.Top <= y)
                {
                    line    = currentLine;
                    nextTop = currentLine.Top + currentLine.Height;
                }
                else
                {
                    nextTop = currentLine.Top;
                    break;
                }
            }

            if (!line.Equals(default(AvaloniaFormattedTextLine)))
            {
                var rects = GetRects();

                for (int c = line.Start; c < line.Start + line.TextLength; c++)
                {
                    var rc = rects[c];
                    if (rc.Contains(point))
                    {
                        return(new TextHitTestResult
                        {
                            IsInside = !(line.TextLength > line.Length),
                            TextPosition = c,
                            IsTrailing = (point.X - rc.X) > rc.Width / 2
                        });
                    }
                }

                int offset = 0;

                if (point.X >= (rects[line.Start].X + line.Width) && line.Length > 0)
                {
                    offset = line.TextLength > line.Length ?
                             line.Length : (line.Length - 1);
                }

                if (y < nextTop)
                {
                    return(new TextHitTestResult
                    {
                        IsInside = false,
                        TextPosition = line.Start + offset,
                        IsTrailing = Text.Length == (line.Start + offset + 1)
                    });
                }
            }

            bool end = point.X > _bounds.Width || point.Y > _lines.Sum(l => l.Height);

            return(new TextHitTestResult()
            {
                IsInside = false,
                IsTrailing = end,
                TextPosition = end ? Text.Length - 1 : 0
            });
        }