描述如何在非等宽文本中处理导航的标准?

Standards describing how navigation is handled in non-monospace text?

对于最近的一个项目,我一直在开发一个简单的文字处理器,并且因为我需要细粒度控制,所以不得不实现很多 text shaping myself. Most of this is fairly straight-forward and described in detail places like here and here

在处理拆分成多行的非等宽文本时,如何处理键盘上的向下或向上按下不太明显。在等宽文本中,算法很简单:将文本插入符向下移动一行,并向右移动相同数量的字符。但是可变宽度字体呢?我试过这样的算法(伪代码):

; Return text offset into next line after navigating down
function moveCaretDown():
  Move text caret to start of next line
  targetPixelOffset := previous pixel offset of caret in line above
  textOffsetIntoLine := 0
  pixelOffsetIntoLine := 0
  prevDelta := Infinity

  for each char in text of new line:
    delta = abs(pixelOffsetIntoLine - targetPixelOffset)

    ; We are now further from the desired cursor offset than before, this must
    ; be closest slot to the caret's previous horizontal offset in this line.
    if (delta > prevDelta):
      return textOffsetIntoLine - 1

    prevDelta = delta
    pixelOffsetIntoLine += measureWidth(char)
    currentOffset++

  ; Else return the offset of the last character in the line
  return length of newline - 1

但我发现它的行为不同于主要网络浏览器 and/or 文本编辑器中的文本输入(如果需要,我可以提出一些具体示例)。 GUI 工具包或文本整形库是否为此使用了一些标准算法?我很惊讶我找不到 W3C 标准,例如,考虑到这是每个网络浏览器都需要的行为。

* 在字符串的正确位置插入换行符,处理参差不齐或完全对齐的文本等

我认为除了遵循 Principle of Least Astonishment 之外没有其他标准。如今,这通常意味着查看主要应用程序的功能,因为这可能是用户熟悉的行为。

在当前行上,您知道当前的水平偏移量。我们称它为 x。我说的是像素位置,而不是自该行开头以来的字符数或字形数。

在目标行上,有一组可以放置插入符的水平偏移量(例如,在字形之间)。因此,您想选择与当前 x 尽可能相似的那些。

此外,如果用户连续多次垂直移动插入符,您可能希望找到最接近原始符号的 x。当用户上下移动时,插入符号可能会水平摆动一点,但您不希望它漂移。一旦用户做了一些有意改变水平偏移的事情(例如,插入一个字符、使用水平箭头、单击鼠标等),这就是更新 x.

的最佳时间

如果您已经有代码可以找到最接近鼠标点击的插入位置,您可以重新使用它,就好像用户点击了当前点上方或下方正好一行的点 x.

我还看到一些编辑器(包括等宽文本编辑器)将行尾视为一种特殊情况。因此,如果您在一行的末尾向上或向下移动,则会移动到前一行或后一行的末尾。这似乎是处理段落末尾参差不齐的右侧文本和短行的好方法。