PDFTron:如何确定文本是否溢出其边界框

PDFTron: How to figure out if text is overflowing its bouding box

我制作了一个包含多行文本字段的 PDF 文档。我想知道如何检查文本是否超出边界。

TextWidget::GetVisibleContentBox()

TextWidget::GetRect()

两者似乎都一样Rect

好的。这是我稍微修改过的函数,用于确定文本字段是否溢出。摘自TCPDF的部分逻辑:

function isTextWidgetOverflowing (PDFTron\TextWidget $annot, float $leading = 9.6) {
    $text = $annot->GetText();

    /** @var PDFTron\Font */
    $font = $annot->GetFont();

    /** @var PDFTron\Rect */
    $rect = $annot->GetRect();

    $length = strlen($text);

    $rectW = $rect->Width();

    $lastSeparator = -1;
    $lines = 1;
    $sum = 0;

    for ($index = 0; $index < $length; $index++) {
        $character = $text[$index];
        $charCode = mb_ord($character);

        if (!($chW = $font->GetWidth($charCode))) {
            $chW = $font->GetMissingWidth();
        }

        $chW /= 1000.0;

        if (($charCode !== 160)
                && (($charCode === 173)
                || preg_match('/[^\S\xa0]/', $character)
                || (($charCode === 45)
                    && ($index > 0) && ($index < ($length - 1))
                    && @preg_match('/[\p{L}]/', $text[$index - 1])
                    && @preg_match('/[\p{L}]/', $text[$index + 1])
                )
            )
        ) {
            $lastSeparator = $index;
        }

        if ((($sum + $chW) > $rectW) || ($charCode === 10)) {
            ++$lines;

            if ($charCode === 10) {
                $lastSeparator = -1;
                $sum = 0;
            } else if ($lastSeparator !== -1) {
                $index = $lastSeparator;
                $lastSeparator = -1;
                $sum = 0;
            } else {
                $sum = $chW;
            }
        } else {
            $sum += $chW;
        }
    }

    if (mb_ord($text[$length - 1]) === 10) {
        --$lines;
    }

    return ($lines * $leading) > $rect->Height();
}

$chW 很有可能有点不对。也许我需要考虑行间距和字体拉伸。在哪里可以找到这些?

另外,如果我能以某种方式从 PDF 文档中获取 $leading,而不是硬编码,那就太好了。

这是确定文本小部件是否有溢出文本的有效解决方案。我唯一想改变的是不依赖于前导参数。

function isTextWidgetOverflowing(PDFTron\TextWidget $annot, float $leading = 9.6) {
    $text = $annot->GetText();

    /** @var PDFTron\Font */
    $font = $annot->GetFont();

    $fontSize = $annot->GetFontSize();

    /** @var PDFTron\Rect */
    $rect = $annot->GetRect();

    $length = strlen($text);

    $rectW = $rect->Width();

    $lastSeparator = -1;
    $lines = 1;
    $sum = 0;

    for ($index = 0; $index < $length; $index++) {
        $char = $text[$index];
        $charCode = mb_ord($char);

        if (!($chW = $font->GetWidth($charCode))) {
            $chW = $font->GetMissingWidth();
        }

        $chW /= (1000.0 / $fontSize);

        if (($charCode !== 160)
            && (($charCode === 173)
                || preg_match('/[^\S\xa0]/', $char)
                || (($charCode === 45)
                    && ($index > 0) && ($index < ($length - 1))
                    && preg_match('/[\p{L}]/', $text[$index - 1])
                    && preg_match('/[\p{L}]/', $text[$index + 1])))
        ) {
            $lastSeparator = $index;
        }

        if ((($sum + $chW) > $rectW) || ($charCode === 10)) {
            ++$lines;

            if ($charCode === 10) {
                $lastSeparator = -1;
                $sum = 0;
            } else if ($lastSeparator !== -1) {
                $index = $lastSeparator;
                $lastSeparator = -1;
                $sum = 0;
            } else {
                $sum = $chW;
            }
        } else {
            $sum += $chW;
        }
    }

    if (mb_ord($text[$length - 1]) === 10) {
        --$lines;
    }

    return ($lines * $leading) > $rect->Height();
}