我找不到关于这个主题的任何信息。是否有一个共同的算法,或者它是不同的编辑器?
Thanks in advance
我假设您想将鼠标在[pixels]
中的位置转换为光标在[char]
中的位置,并返回。
渲染API通常提供以像素为单位返回文本宽度和高度的函数,而不是渲染它。这可以用于字符和像素位置之间的转换。
(cx,cy) [char] -> (mx,my) [pixels]
可以直接完成,例如(VCL):
mx = TextWidth(Substring(line[cy],1,cx))
my = FontHeight*cy
其中line[]
保存编辑器的行。TextWidth
与渲染文本的特定视觉对象画布紧密相关,因此object->Canvas->TextWidth(...
和FontHeight
应该是编辑器的行高(以像素为单位)。
反向转换(mx,my) [pixels] -> (cx,cy) [char]
更棘手。cy
坐标是简单的除法,但cx
必须迭代。对于普通文本窗口是简单的线性O(n)
搜索足够(以像素为单位获得字符串宽度,因此测试第一个字符,然后第一个2,然后第一个3…直到x >= mx
).
然而,一旦行太长,你可以使用二分搜索来加快速度。另一种选择是使用avg字符宽度将鼠标位置除以它以获得近似字符位置,然后简单地从该位置线性搜索。
注意,一旦你开始使用Unicode编码,如UTF-8和或esc编码,如制表符,你需要记住,avg字符宽度并不总是一个好方法。
线性搜索的例子:
cy = my/FontHeight
for (cx=0;;)
{
if (line[cy].Length()<=cx) break; // end of line reached
if (mx<TextWidth(Substring(line[cy],1,cx))) break;
cx++;
}
如果您不使用VCL,那么您需要在您的环境中找到对应的TextWidth
。Substring
也是如此。注意代码示例不是直接在回答编辑器中测试和编写的,因此可能会出现错误(如语法和关闭)
无论如何,现代编程环境已经准备好使用编辑器组件(如VCL中的TMemo
),它已经实现了所有这些功能。