ZF-313: TTFBox or TextWidth/Height function (word wrapping functionality)


Problem: When using the drawText function to write a string that is longer than the page, there is no WordWrap. Is there a way to print text wrapped or to find out the width and height of the string that is about to be printed?


I am working on some advanced layout classes that will take care of wrapping long lines for you. This code won't be ready for several more weeks. In the meantime, you may be able to use this function:

* 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.
* @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-16BE', $string);
    $characters = array();
    for ($i = 0; $i < strlen($drawingString); $i++) {
        $characters[] = (ord($drawingString[$i++]) << 8) | ord($drawingString[$i]);
    $glyphs = $font->cmap->glyphNumbersForCharacters($characters);
    $widths = $font->widthsForGlyphs($glyphs);
    $stringWidth = (array_sum($widths) / $font->getUnitsPerEm()) * $fontSize;
    return $stringWidth;

$font = Zend_Pdf_FontFactory::fontWithName(Zend_Pdf_Const::FONT_HELVETICA);
$stringWidth = widthForStringUsingFontSize('Hello world!', $font, 12);

@Wille Alberty: Amazing, this is 100% what I have needed! Thank you very much!

Changing fix version to unknown.

Changing fix version to 0.6.0.

Summary is changed to describe problem more clear.

Depends on other text formatting tasks (canvases, paragraphs and so on)

Assignee is changed to postpone issue to post-v1.0 period

Postponed to post-v1.0

This only partially alleviates the metrics required for word wrapping though. This may be neat, but the instance where it doesn't help, is where you have a long string, need to word-wrap it, but need to know at which width a line should be cut without cutting words.

PHP inherently offers us the wordwrap function, which allows us to cut a string into an array where lines don't exceed a certain width, taking word composition into consideration. It's useless in this case though, since a 'max width' is very variable when font glyphs are of variable sizes.

Is there a function in Zend_PDF somewhat akin to the above, which allows us to determine a cut-strategy given: - a font - a font size - a page width (or width-coordinate restriction) - a (possibly multi-line) string of text?

Thanks. Alex

There is a new Zend_Font Component Proposal available for this:…

I would love to see a little bit progress with Zend_Pdf.

Unassigning Zend_Pdf issues currently assigned to me pending decision on ZF 2.0 release timeframe and potential contribution of comprehensive changeset.

Alex, could you please look at this issue and mark it 'postponed' if we won't be addressing it before 1.8. Note that it has several votes.

A few minor comments that might save people some time:

  1. The following line:

{{$glyphs = $font->cmap->glyphNumbersForCharacters($characters);}}

...needs to be changed to this in order to work with later versions of ZF (eg. 1.10.1):

{{$glyphs = $font->glyphNumbersForCharacters($characters);}}

  1. The following line to test the function:

{{$font = Zend_Pdf_FontFactory::fontWithName(Zend_Pdf_Const::FONT_HELVETICA);}}

...needs to be changed to this in order to work with later versions of ZF (eg. 1.10.1):

{{$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);}}

  1. The function won't work with extracted fonts, only standard fonts or fonts loaded from {{ttf}} files.

Otherwise excellent function (I see it made its way into {{Zend_Barcode_Renderer_Pdf}}). Many thanks!