Zend_Pdf : obtenir la largeur d'un texte

Zend_Pdf

Zend_Pdf_Page ne dispose pas de méthode qui permette de déterminer la largeur d'une chaine de caractères, ce qui pose des problèmes car cette information est indispensable pour centrer ou aligner un texte à droite.

Heureusement, Zend_Pdf_Resource_Font dispose de quelques méthodes qui nous permettent de réaliser cette opération.

Il faut d'abord convertir notre chaine de caractère en tableau de codes Unicode. PHP ne dispose pas de fonction pour retrouver un code Unicode à partir d'un caractère (similaire à ord pour les caractères ASCII), nous devons donc écrire notre propre fonction. J'ai trouvé dans la doc PHP cette fonction qui fait le boulot :

<?php
function uniord($u) {
  
$c unpack('N'mb_convert_encoding($u'UCS-4BE''UTF-8'));
  return 
$c[1];
}
?>

Cette fonction nécessite que l'extension mb_string soit chargée.

On utilise ensuite Zend_Pdf_Resource_Font::glyphNumbersForCharacters pour convertir les code Unicode en numéros de caractères, puis Zend_Pdf_Resource_Font::widthsForGlyphs pour retrouver les largeurs et enfin Zend_Pdf_Resource_Font::getUnitsPerEm pour retrouver le nombre de points par em.

On termine en multipliant par la hauteur de la police.

<?php
class Wiip_Pdf_Page extends Zend_Pdf_Page
{
    
/**
     * Retourne le code Unicode correspondant au caractère
     *
     * @param string $char
     * @return int
     */
    
public function uniord($char)
    {
        
$c unpack('N'mb_convert_encoding($char'UCS-4BE''UTF-8'));
        return 
$c[1];
    }
    
    
/**
     * Retourne la largeur du texte en points
     *
     * @param string $text
     * @param string $charEncoding
     * @return float
     */
    
public function getTextWidth($text$charEncoding null)
    {
        
// Transforme le texte en tableau de caractères
        
mb_internal_encoding($charEncoding);
        
$charArray = array();
        for (
$x 0$x mb_strlen($text); $x++) {
            
$charArray[] = $this->uniord(mb_substr($text$x1));
        }

        
$font $this->getFont();

        
// Convertit les codes Unicode en numéros de caractères
        
$charArray $font->glyphNumbersForCharacters($charArray);

        
// Retrouve la largeur de chaque caractère en em
        
$lengths $font->widthsForGlyphs($charArray);

        
// Additionne toutes les largeurs
        
$fontGlyphWidth array_sum($lengths);

        
// Convertit en points
        
$width $fontGlyphWidth/$font->getUnitsPerEm() * $this->getFontSize();

        return 
$width;
    }
}
?>

On doit également surcharger la méthode newPage de Zend_Pdf pour qu'elle renvoie une instance de Wiip_Pdf_Page :

<?php
class Wiip_Pdf extends Zend_Pdf
{
    public function 
newPage($param1$param2 null)
    {
        if (
$param2 === null) {
            return new 
Wiip_Pdf_Page($param1$this->_objFactory);
        } else {
            return new 
Wiip_Pdf_Page($param1$param2$this->_objFactory);
        }
    }
}
?>

A lire également

Ajouter un commentaire