Zend_Pdf satır kaydırma için geçerli yazı tipi metin dizesinin uzunluğunu hesaplama

2 Cevap php

Herkes bir sayfa boyunca metin bir parça belli bir font ve boyut olarak tüketmek kaç puan hesaplamak için kolay bir yol var mı? (Kolay = minimum satır kod + hesaplama ucuz). Zend_Pdf) getGlyphForCharacter için her karakter (bazı çok pahalı çağrıları dışında, bunu yapan bir işleve sahip görünmüyor, getUnitsPerEm () ve getWidthsForGlyph ().

Ben her sayfada birkaç tablo ile bir çok sayfalı PDF üreten ve sütunlar içinde metin sarmak gerekir ediyorum. Zaten bunu oluşturmak için birkaç saniye alıyor, ve ben bunun çok uzun almak istemiyorum ya da ben arka plan görevleri, vs ilerleme çubukları ile karıştırmasını başlamak gerekir

Her dize üzerinde bu kadar ekleyerek, sonra kullanılan her yazı tipi boyutu her karakterin (puan) genişliği ön işlem olduğu ile geldi tek çözüm. Hala oldukça pahalı.

Ben bir şey eksik? Yoksa basit bir şey var?

teşekkürler!

2 Cevap

Tam genişlikleri hesaplamak için bir yol oldukça Gorilla3D's worst case algorithm kullanmak yerine, var.

http://devzone.zend.com/article/2525-Zend%5FPdf-tutorial#comments-2535 bu kodu deneyin

Ben sağa hizalanmış metin için uzaklıklar hesaplamak benim uygulamada kullandım ve işe yarıyor

/**
* Returns the total width in points of the string using the specified font and
* size.
*
* This is not the most efficient way to perform this calculation. I'm
* concentrating optimization efforts on the upcoming layout manager class.
* Similar calculations exist inside the layout manager class, but widths are
* generally calculated only after determining line fragments.
* 
* @link http://devzone.zend.com/article/2525-Zend_Pdf-tutorial#comments-2535 
* @param string $string
* @param Zend_Pdf_Resource_Font $font
* @param float $fontSize Font size in points
* @return float
*/
function widthForStringUsingFontSize($string, $font, $fontSize)
{
     $drawingString = iconv('UTF-8', 'UTF-16BE//IGNORE', $string);
     $characters = array();
     for ($i = 0; $i < strlen($drawingString); $i++) {
         $characters[] = (ord($drawingString[$i++]) << 8 ) | ord($drawingString[$i]);
     }
     $glyphs = $font->glyphNumbersForCharacters($characters);
     $widths = $font->widthsForGlyphs($glyphs);
     $stringWidth = (array_sum($widths) / $font->getUnitsPerEm()) * $fontSize;
     return $stringWidth;
 }

Performansa gelince, ben bir komut yoğun kullanılan bu değil ama yavaş hayal edebiliyorum. Ben mümkünse, diske yazma PDF'leri önermek, bu nedenle görüşlerini çok hızlı tekrarlayın ve mümkünse önbelleğe / sabit veri kodlama olur.

Biraz daha bu aşkın Düşünme. Senin kullanarak yazı tipi geniş Glifler'i almak ve esaslı her karakter için genişlik olarak. Bu alışkanlık doğru olabilir ama işareti geçmiş metin bastırıyor önleyecektir.

$pdf = new Zend_Pdf();
$font      = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_COURIER); 
$font_size = $pdf->getFontSize();


$letters = array();
foreach(range(0, 127) as $idx)
{
    array_push($letters, chr($idx));
}
$max_width = max($font->widthsForGlyphs($letters));

// Text wrapping settings
$text_font_size = $max_width; // widest possible glyph
$text_max_width = 238;        // 238px

// Text wrapping calcs
$posible_character_limit = round($text_max_width / $text_font_size);
$text = wordwrap($text, $posible_character_limit, "@newline@");
$text = explode('@newline@', $text);