【问题标题】:How to implement text selecting?如何实现文本选择?
【发布时间】:2010-12-30 14:26:05
【问题描述】:

我的问题不是基于语言或基于操作系统。我猜每个系统都提供某种 TextOut(text, x, y) 方法。我正在寻找一些指南或文章我应该如何实现输出文本的选择。找不到任何相关信息。

我唯一想到的是这样的:

当用户单击文本画布上的某个点时,我知道该点的坐标。我需要计算它在我的文本缓冲区中的确切位置。因此,我从缓冲区的开头开始遍历,并对每个字符(或文本块)应用样式(如果有的话)。在此之后,我知道在给定样式之后,字母已经给定大小。我将其宽度和高度添加到先前计算的 X、Y 坐标中。这样,我就在遍历缓冲区,直到计算出的位置还没有到达用户点击过的点。在我到达某个偏移范围内的点后,我有了选择的起点。

这是基本思想。我不知道这是否很好,我想知道这是如何真正做到的,例如在 Firefox 中。我知道我可以浏览资源,如果我别无选择,我会这样做。但首先我试图找到一些关于它的文章......

【问题讨论】:

  • 确实很有趣。我建议查看开源代码,看看其他人是如何解决这个问题的。

标签: language-agnostic text selection


【解决方案1】:

选择文本本质上特定于包含它的控件以及它存储该文本的方式。

一个非常简单(尽管可能效率低下的方法)是在单击某个点时运行您正在使用的文本流算法,并在您到达最接近该点的位置时停止该算法。更高级的控件可能会缓存文本布局,以便更有效地进行选择或绘制其内容。根据您对 CPU 时间或内存的重视程度,可以使用缓存和特殊情况来降低“命中测试”的成本。

如果您可以进行任何断言(控件中只有一种字体,因此每行具有相同的高度),那么可以通过按行索引字体布局然后进行简单的算术找出哪个来使这些测试更便宜行被点击。如果您的文本控件也使用等宽字体(每个字符占用相同的宽度和高度),那么您就更幸运了,因为您可以通过查找表和两个简单​​的分区直接跳转到字符信息。

请记住,从头开始编写文本控件非常困难。为获得最佳实践,您应该将文档内容与显示信息分开。这样做的原因是因为文本本身需要经常编辑,因此可以在数据端使用诸如 Ropes 或 Gap Buffers 之类的算法来提供更快的插入符号周围的插入。每次编辑文本时也必须渲染它,这涉及获取该数据并通过某种格式/流算法运行它以确定它需要如何显示给用户。 这两方面都需要大量的算法,这些算法可能很烦人。

很遗憾,使用本机 TextOut 函数对您没有帮助。您将需要使用为单个字符提供文本范围的方法,并且更高级的(例如多行)控件通常必须使用此信息自己渲染字符。像 TextOut 这样的函数并不是为了处理闪烁的插入插入符号,或者对文本布局执行增量更新。虽然某些 TextOut 样式的函数可能支持自动换行和对齐,但它们还需要重新渲染整个字符串,这与您需要在控件中处理的文本量成正比。

【讨论】:

    【解决方案2】:

    您的思维水平远远低于必要水平(不是侮辱。您认为您需要做的工作比实际需要的多得多)。大多数(如果不是全部)支持 GUI 的语言也将具有某种形式的 selectionRange,它可以为您提供被选择的字符串或字符串中的开始和停止索引。

    使用现代语言,您永远不必计算像素和字符宽度。

    对于 Javascript 中的文本选择,请参阅这个问题:Understanding what goes on with textarea selection with JavaScript

    【讨论】:

    • 感谢您的回答:) 但是我确实需要进入较低级别。如果我想实现自己的 textarea 怎么办?这正是我想要做的,我想实现一个可以放置不同格式的文本并将其与图像结合的区域。这就是为什么我询问实施细节的原因,因为我想知道如何自己做到这一点......
    • 你不可能找到一篇关于浏览器是如何做到这一点的文章,因为只有那些真正编写它们的核心人才会想到这一点。
    猜你喜欢
    • 2020-09-17
    • 2012-11-11
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多