【问题标题】:fPDF: how to strikeout/strikethrough justified text in multicell?fPDF:如何在多单元格中删除/删除对齐的文本?
【发布时间】:2011-02-19 10:33:16
【问题描述】:

我正在使用 fPDF 生成 PDF。

我需要删除 MultiCell 中的长文本。文字左右对齐,这可能是问题的根源。

这是我的代码:

//get the starting x and y of the cell to strikeout
$strikeout_y_start = $pdf->GetY();
$strikeout_x = $pdf->getX();
$strikeText = "Some text with no New Lines (\n), which is wrapped automaticly, cause it is  very very very very very very very very very very long long long long long long long long long long long long long long long long long long"
//draw the text
$pdf->MultiCell(180, 4, $strikeText);
//get the y end of cell
$strikeout_y_end = $pdf->GetY();
$strikeout_y = $strikeout_y_start+2;
$strikeCount = 0;
for ($strikeout_y; $strikeout_y < $strikeout_y_end - 4; $strikeout_y+=4) {
    $strikeCount++;
    //strike out the full width of all lines but last one - works OK
    $pdf->Line($strikeout_x, $strikeout_y, $strikeout_x + 180, $strikeout_y);
}

//this works, but gives incorrect results
$width = $pdf->GetStringWidth($strikeText);
$width = $width - $strikeCount*180;
//the line below will strike out some text, but not all the letters of last line
$pdf->line($strikeout_x, $strikeout_y, $strikeout_x+$width, $strikeout_y);

问题在于,由于多单元格中的文本是合理的(并且必须如此),前几行中的空格比 GetStringWidth 假设的要宽,因此 GetStringWidth 低估了此文本的整个宽度。

因此,最后一行被划掉了,比如说,70%,而它末尾的一些字母没有被划掉。

任何想法如何计算多单元格中最后一行的宽度?

【问题讨论】:

    标签: php fpdf strikethrough


    【解决方案1】:

    我自己找到了解决方案。 很抱歉问了一些不必要的问题。

    这是我所做的:

    class VeraPDF extends FPDF {
    
        /**
         * Returns width of the last line in a multicell
         * useful for strike out / strike through 
         * 
         *
         * @param string $s - the string measured
         * @param int $lineWidth - with of the cell/line
         * @return int
         */
        function GetStringWidth_JustifiedLastLineWidth($s, $lineWidth)
        {
            //Get width of a string in the current font
            $s=(string)$s;
            $words = split(' ',$s);
            $cw=&$this->CurrentFont['cw'];
            $w=0;
            $spaceWidth = $this->GetStringWidth(' ');
    
            for($i=0, $wordsCount = count($words); $i<$wordsCount; $i++){
                // sum up all the words width, and add space withs between the words
                $w += $this->GetStringWidth($words[$i]) + $spaceWidth;
                if ($w > $lineWidth) {
                    //if current width is more than the line width, then the current word
                    //will be moved to next line, we need to count it again
                    $i--;
                }
                if ($w >= $lineWidth) {
                    //if the current width is equal or grater than the line width, 
                    //we need to reset current width, and count the width of remaining text
                    $w = 0;
                }
            }
            //at last, we have only the width of the text that remain on the last line!
            return $w;
        }    
    }
    

    希望这对某人有所帮助:)

    【讨论】:

    • 很抱歉回答我自己。在我在这里发布一个问题后,我就知道如何解决它
    【解决方案2】:

    前几行的空格更宽 比 GetStringWidth 假设的,所以 GetStringWidth 低估了完整的 此文本的宽度。

    您是否尝试过计算空格并自己添加缺少的宽度。假设每个空间应该是 5px 宽,但是 fpdf 估计它是 4px,也许你可以在最后将每个空间添加 1px 到总宽度。

    【讨论】:

    • 感谢您的回答。实际上 fpdf 计算当前字体中定义的空间宽度。但是,当文本被换行并对齐时,空格会“增长”以占据当行填充到其末尾时移动到下一行的单词所占用的空格。我刚刚发布了一个解决方案,它基于您需要计算两次包装的单词并完全忽略完全填充的行的规则。
    猜你喜欢
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多