Zend_Pdf: align drawn text on right or center it horizontally

Below is the code I used to align drawn text on the right or center it within provided width.

As stated in http://framework.zend.com/issues/browse/ZF-7144,  use of Zend_Pdf_Page subclass is not easy on ZF 1.8.4 => I subclassed Zend_Pdf and implemented within this class instead.

Below code relies on function to find out width of text to be generated (see Zend_Pdf: find out width of text to be drawn) and also incorporates small code improvement to handle multi-line text (see Zend_Pdf: draw multi-line text).

Here it is:

require_once 'Zend/Pdf.php';

* Represent an order/bill pdf
class Library_Pdf_Base extends Zend_Pdf
 * Align text at left of provided coordinates
 const TEXT_ALIGN_LEFT = 'left';

 * Align text at right of provided coordinates
 const TEXT_ALIGN_RIGHT = 'right';

 * Center-text horizontally within provided coordinates
 const TEXT_ALIGN_CENTER = 'center';
 * Extension of basic draw-text function to allow it to vertically center text
 * @param Zend_Pdf_Page $page
 * @param string $text
 * @param int $x1
 * @param int $y1
 * @param int $x2
 * @param int $position
 * @param string $encoding
 * @return self
 public function drawText(Zend_Pdf_Page $page, $text, $x1, $y1, $x2 = null, $position = self::TEXT_ALIGN_LEFT, $encoding = null)
  $bottom = $y1; // could do the same for vertical-centering
  switch ($position) {
   case self::TEXT_ALIGN_LEFT:
    $left = $x1;
   case self::TEXT_ALIGN_RIGHT:
    $text_width = $this->getTextWidth($text, $page->getFont(), $page->getFontSize());
    $left = $x1 - $text_width;
   case self::TEXT_ALIGN_CENTER:
    if (null === $x2) {
     throw new Exception("Cannot center text horizontally, x2 is not provided");
    $text_width = $this->getTextWidth($text, $page->getFont(), $page->getFontSize());
    $box_width = $x2 - $x1;
    $left = $x1 + ($box_width - $text_width) / 2;
    throw new Exception("Invalid position value \"$position\"");

  // display multi-line text
  foreach (explode(PHP_EOL, $text) as $i => $line) {
   $page->drawText($line, $left, $bottom - $i * $page->getFontSize(), $encoding);
  return $this;

 * Return length of generated string in points
 * @param string $string
 * @param Zend_Pdf_Resource_Font $font
 * @param int $font_size
 * @return double
 public function getTextWidth($text, Zend_Pdf_Resource_Font $font, $font_size)
  $drawing_text = iconv('', 'UTF-16BE', $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;

So far it worked real great for him, I hope some folks will find it useful to and improve it.


6 Comments: Trackback URL | Comments RSS

  1. jcerdan Says:

    Very very useful! thanks!
    I replaced last lines of drawText() by this:

    // display multi-line text
    foreach (explode(PHP_EOL, $text) as $i => $line) {
    $page->drawText($line, $left, $bottom – $i * $page->getFontSize(), $encoding);
    $height = $bottom – $i * $page->getFontSize();
    return $height;

    Like this, this function returns the $height position if you need to write just below!

  2. tjunicho Says:

    doesnt seem to work for JAPANESE charcters.

    is it relevant to multi-bites?

  3. Greg Says:

    Good thing, thanks.

    therefore, you inctroduced an interface break : the $x2 and $position parameters should be placed after the $encoding parameter, as shown here, nothing seems to break, but it does :

    // In your app code :
    $obj = new Library_Pdf_Base();

    // later, in a Zend Framework standard class :
    if ($obj instanceof Zend_Pdf) {
    $obj->drawText($page, ‘Hello World!’, 35, 100, ‘UTF-8’) // Break!


  4. max4ever Says:

    Thanks for the getTextWidth function 😀

  5. MaxFor222 Says:

    🙂 good job, thanx 😉

  6. Jamie Saunders Says:

    Great, plugged this into Magento’s PDF functionality (built on the Zend Framework), and it work first time. Thanks!

Post a Comment

Your email is never published nor shared. You're allow to say what you want...

Warning: fsockopen() [function.fsockopen]: php_network_getaddresses: getaddrinfo failed: Name or service not known in /home/remydamo/websites/qc4blog/www/wp-content/plugins/sweetcaptcha-revolutionary-free-captcha-service/library/sweetcaptcha.php on line 81

Warning: fsockopen() [function.fsockopen]: unable to connect to www.sweetcaptcha.com:80 (php_network_getaddresses: getaddrinfo failed: Name or service not known) in /home/remydamo/websites/qc4blog/www/wp-content/plugins/sweetcaptcha-revolutionary-free-captcha-service/library/sweetcaptcha.php on line 81