开发者

Why is this code to center text on a PDF using the PHP Zend_Pdf Library not working?

开发者 https://www.devze.com 2023-04-12 09:14 出处:网络
I\'m attempting to dynamically create PDF documents on the server and send them to the client using the Zend_Pdf library. All text on the PDF needs to be center aligned to the page, which will be lett

I'm attempting to dynamically create PDF documents on the server and send them to the client using the Zend_Pdf library. All text on the PDF needs to be center aligned to the page, which will be letter-sized, landscape. Using functions that I have found multiple times on various sites, I'm having a problem - the center justification is off. All text is appearing way too far to the left. Here is my code:

<?
require('Zend/Pdf.php');

$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
$pdf = new Zend_Pdf();

// Create a new page, add to page listing
$pdfPage = $pdf->newPage(Zend_开发者_如何学编程Pdf_Page::SIZE_LETTER_LANDSCAPE);
$pdf->pages[] = $pdfPage;

// Add certify that
$pdfPage->setFont($font, 15.75);
drawCenteredText($pdfPage, "THIS IS TO CERTIFY THAT", 378);

// Add name
$pdfPage->setFont($font, 39.75);
drawCenteredText($pdfPage, "Example Name", 314.25);

// Headers
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=\"cert.pdf\"");
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');

// Output PDF
echo $pdf->render();


function drawCenteredText($page, $text, $bottom) {  
    $text_width = getTextWidth($text, $page->getFont(), $page->getFontSize());
    $box_width = $page->getWidth();
    $left = ($box_width - $text_width) / 2;

    $page->drawText($text, $left, $bottom, 'UTF-8');
}

function getTextWidth($text, $font, $font_size) {
    $drawing_text = iconv('', 'UTF-8', $text);
    $characters    = array();
    for ($i = 0; $i < strlen($drawing_text); $i++) {
        $characters[] = (ord($drawing_text[$i++]) << 8) | ord ($drawing_text[$i]);
    }
    $glyphs        = $font->glyphNumbersForCharacters($characters);
    $widths        = $font->widthsForGlyphs($glyphs);
    $text_width   = (array_sum($widths) / $font->getUnitsPerEm()) * $font_size;
    return $text_width;
}

?>

...and this is the result.

Why is this code to center text on a PDF using the PHP Zend_Pdf Library not working?


In case anyone else runs into a similar problem, the issue is here:

function getTextWidth($text, $font, $font_size) {
    $drawing_text = iconv('', 'UTF-8', $text);
    $characters    = array();
    for ($i = 0; $i < strlen($drawing_text); $i++) {
        $characters[] = (ord($drawing_text[$i++]) << 8) | ord ($drawing_text[$i]);
    }
    $glyphs        = $font->glyphNumbersForCharacters($characters);
    $widths        = $font->widthsForGlyphs($glyphs);
    $text_width   = (array_sum($widths) / $font->getUnitsPerEm()) * $font_size;
    return $text_width;
}

When building the characters array, the characters are being loaded incorrectly - 8 bits, not 16.

$characters[] = ord ($drawing_text[$i]);

This solves the problem, and correctly calculates text width.


try to use this function:

/**
    * Return length of generated string in points
    *
    * @param string                     $text
    * @param Zend_Pdf_Resource_Font|Zend_Pdf_Page     $font
    * @param int                         $fontSize
    * @return double
*/
public static function getTextWidth($text, $resource, $fontSize = null/*, $encoding = null*/) {
    //if( $encoding == null ) $encoding = 'UTF-8';

    if( $resource instanceof Zend_Pdf_Page ){
        $font = $resource->getFont();
        $fontSize = $resource->getFontSize();
    }elseif( $resource instanceof Zend_Pdf_Resource_Font ){
        $font = $resource;
        if( $fontSize === null ) throw new Exception('The fontsize is unknown');
    }

    if( !$font instanceof Zend_Pdf_Resource_Font ){
        throw new Exception('Invalid resource passed');
    }

    $drawingText = $text;//iconv ( '', $encoding, $text );
    $characters = array ();
    for($i = 0; $i < strlen ( $drawingText ); $i ++) {
        $characters [] = ord ( $drawingText [$i] );
    }
    $glyphs = $font->glyphNumbersForCharacters ( $characters );
    $widths = $font->widthsForGlyphs ( $glyphs );

    $textWidth = (array_sum ( $widths ) / $font->getUnitsPerEm ()) * $fontSize;
    return $textWidth;
}

and call it on your render function, like:

if ($this->getAlign() == self::TEXT_ALIGN_CENTER)
{
        $x = ($currentPage->getWidth() - $this->getTextWidth($text, $currentPage)) / 2;
}
...
$currentPage->drawText($text, $x, $y, ...);


If there is anyone looking for solution to Latin american characters like ó,á,é this worked for me

try {
          $drawing_text = iconv('UTF-8', 'UTF-8', $text);
          $characters    = array();
          for ($i = 0; $i < strlen($drawing_text); $i++) {
              $characters[] = ord ($drawing_text[$i]);
          }
          $glyphs        = $font->glyphNumbersForCharacters($characters);
          $widths        = $font->widthsForGlyphs($glyphs);
          $text_width   = (array_sum($widths) / $font->getUnitsPerEm()) * $font_size;
          return $text_width;
        } catch (\Exception $e) {
          //echo "$e";
        }
0

精彩评论

暂无评论...
验证码 换一张
取 消