iText 的 SameLine 功能背后的逻辑是什么?

What is the logic behind iText's SameLine function?

我正在使用 iText 7 从 PDF 中提取文本,superscript/subscript 个字符经常出现在上方或下方的行中。

我已经追踪到 TextChunkLocationSameLine 方法,我正在创建这个 class 的自定义版本,这样我就可以调整逻辑(连同还要处理其他一些事情,例如自动截断页眉和页脚)。但是我对默认实现中此方法的最后一行有点困惑:

https://github.com/itext/itext7-dotnet/blob/develop/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/TextChunkLocationDefaultImp.cs#L144

public virtual bool SameLine(ITextChunkLocation @as) {
  if (OrientationMagnitude() != @as.OrientationMagnitude()) {
    return false;
  }
  float distPerpendicularDiff = DistPerpendicular() - @as.DistPerpendicular();
  if (distPerpendicularDiff == 0) {
    return true;
  }
  LineSegment mySegment = new LineSegment(startLocation, endLocation);
  LineSegment otherSegment = new LineSegment(@as.GetStartLocation(), @as.GetEndLocation());
  return Math.Abs(distPerpendicularDiff) <= 
    DIACRITICAL_MARKS_ALLOWED_VERTICAL_DEVIATION
    && (mySegment.GetLength() == 0 || otherSegment.GetLength() == 0);
}

我理解与 DIACRITICAL_MARKS_ALLOWED_VERTICAL_DEVIATION 的比较。我不明白为什么两条线段中的至少一条 必须 的长度为 0 才能成为 "on the same line."

如果一个文本块没有对角线长度,这是否意味着文本块是空的,因此是否在同一行上是一个没有实际意义的问题?

这个逻辑如何 return true 用于变音符号......或者用于两个文本块应该在同一行但稍微错位的任何其他情况?

根据所讨论的字体和变音符号,字体可能不包含每个需要的字符组合和标记为字形。相反,可能只有一个带有相关标记的单独字形,并且通过在同一位置绘制字符字形和标记字形来绘制带有该标记的字符。

为了让它们在同一位置绘制,标记的字形虽然实际宽度不为零,但在绘制时不会推进字形绘制位置。

此外,根据与它组合的字符的不同,可能必须在不同的高度绘制变音标记,特别是如果该字符与多个标记组合。

因此,根据您的问题,...

If a text chunk has no diagonal line length, wouldn't that mean the text chunk is empty, and thus it's a moot point to wonder if it is or isn't on the same line?

如果变音标记字形与字符字形组合的高度与正常高度不同,则该标记字形本身形成一个文本块,其 DistPerpendicular 值不同于其周围块的值同一条线。

由于标记字形不推进文本插入点,并且块基线的长度本质上是绘制字形的字符推进的总和,因此仅​​包含变音标记的块的长度为0 .

因此,为了识别这种情况,iText 检查 DistPerpendicular 差异(尽管不是 0)是否不是太大,以及这些有问题的块之一是否具有零长度:

return Math.Abs(distPerpendicularDiff) <= DIACRITICAL_MARKS_ALLOWED_VERTICAL_DEVIATION
    && (mySegment.GetLength() == 0 || otherSegment.GetLength() == 0);