private CharacterPositionInfo GetCharacterAtPoint(Point pt) { CharacterPositionInfo ret = new CharacterPositionInfo(); //find line int line_index = GetLineIndexFromPoint(pt); //если pt не соответсвует ни одной линии... if (line_index == -1) { ret.CharIndex = -1; ret.OffsetToNextCaretPosition = 0; ret.PositionType = CharacterPositionType.AfterEnd; ret.Xoffset = pt.X; return(ret); } //если линия найдена... ret = lines_info[line_index].GetCharacterIndexAtX(pt.X - Bounds.X); //поправляем, чтобы ret.CharIndex был бы относительно экрана ret.CharIndex = ret.CharIndex + lines_info[line_index].CharFirst; return(ret); }
public CharacterPositionInfo GetCharacterIndexAtX(int xOffset) { return(CharacterPositionInfo.FromXoffset(ssa_struct_ptr, xOffset)); }
public HitTextResult HitTest(Point pt) { HitTextResult ret = new HitTextResult(); if (LinesCount == 0) { ret.CharacterIndex = -1; ret.CharacterIndexInLine = -1; ret.LineIndex = -1; ret.HitTextType = HitTextType.BeforeText; return(ret); } if (pt.Y < lines_info[0].ReferensePoint.Y) { ret.CharacterIndex = -1; ret.CharacterIndexInLine = -1; ret.LineIndex = -1; ret.HitTextType = HitTextType.BeforeText; return(ret); } if (pt.Y > lines_info[LinesCount - 1].ReferensePoint.Y + lines_info[LinesCount - 1].Extent.Height) { ret.CharacterIndex = -1; ret.CharacterIndexInLine = -1; ret.LineIndex = -1; ret.HitTextType = HitTextType.AfterText; return(ret); } int line_index = GetLineIndexFromPoint(pt); if (line_index == -1) { ret.CharacterIndex = -1; ret.CharacterIndexInLine = -1; ret.LineIndex = -1; ret.HitTextType = HitTextType.Undefined; return(ret); } CharacterPositionInfo cpi = lines_info[line_index].GetCharacterIndexAtX(pt.X - lines_info[line_index].ReferensePoint.X); ret.CharacterIndex = cpi.CharIndex + lines_info[line_index].CharFirst; ret.CharacterIndexInLine = cpi.CharIndex; ret.LineIndex = line_index; switch (cpi.PositionType) { case CharacterPositionType.LeadingEdge: case CharacterPositionType.TrailingEdge: case CharacterPositionType.ClusterPart: ret.HitTextType = HitTextType.Glyph; break; case CharacterPositionType.BeforeBeginning: ret.HitTextType = HitTextType.BeforeOfLine; break; case CharacterPositionType.AfterEnd: ret.HitTextType = HitTextType.AfterOfLine; break; } return(ret); }
public Point GetCaretPosition(int char_index, out bool outside) { Point ret = new Point(); //найдем линию int line_index = GetLineIndexFromCharacterIndex(char_index); if (line_index == -1) { outside = true; return(ret); } //позиция внутри линии int char_index_in_line = char_index - lines_info[line_index].CharFirst; //а что если запрашивается позиция в коце текста? //тогда придется вернуть trailing edge предыдущего символа //при этом если предыдущий символ \n, то каретку надо бы поставить на следующую строку //и проверить не вылазиет ли она за пределы экрана; //а если предыдущего нет, то есть текст пуст вернем вехний левый угол bool is_trailing_edge = false; if (char_index_in_line >= lines_info[line_index].CharLength) { if (char_index_in_line > 0) { char_index_in_line = char_index_in_line - 1; is_trailing_edge = true; char pre_char = GetChar(lines_info[line_index].CharFirst + char_index_in_line); if (pre_char == '\n') { ret = lines_info[line_index].ReferensePoint; ret.Y = ret.Y + lines_info[line_index].Extent.Height; outside = (ret.Y > Bounds.Bottom); return(ret); } } else { ret = lines_info[line_index].ReferensePoint; outside = false; return(ret); } } CharacterPositionInfo char_info = lines_info[line_index].GetX_AtCharacterIndex (char_index_in_line, is_trailing_edge); ret = new Point(char_info.Xoffset + Bounds.X, lines_info[line_index].ReferensePoint.Y); //System.Windows.Forms.MessageBox.Show // (ret.ToString() + // " line #" + line_index.ToString() + // "; char #" + char_index_in_line.ToString() + // "; line first char #" + lines_info[line_index].CharFirst.ToString() + // "; line char length " + lines_info[line_index].CharLength.ToString() + // "; char: " + char.ToString(GetChar(char_index))); outside = false; return(ret); }