public function render($ge)
 {
     //            BpRectangle::render($ge);
     $sx = $ge->tx($this->sx());
     $sy = $ge->ty($this->sy());
     $ex = $ge->tx($this->ex());
     $ey = $ge->ty($this->ey());
     $width = $ex - $sx - $this->margin() * 2;
     $height = $ey - $sy - $this->margin() * 2;
     $lines = array();
     $cur_words = array();
     $cur_width = 0;
     $cur_line = '';
     if ($this->fontSize() !== '') {
         $font_size = $this->fontSize();
         $line_height = BpFontMetrics::getLineHeightFromFontSize($this->font(), $this->string(), $this->fontSize());
     } else {
         $font_size = BpFontMetrics::getFontSizeFromLineHeight($this->font(), $this->string(), $this->lineHeight());
         $line_height = $this->lineHeight();
     }
     $words = explode(' ', $this->string());
     foreach ($words as $word) {
         $my_words = $cur_words;
         $my_words[] = $word;
         $cur_width = BpFontMetrics::getWidth($this->font(), implode(' ', $my_words), $font_size);
         if ($cur_width <= $height) {
             $cur_words[] = $word;
         } else {
             $lines[] = implode(' ', $cur_words);
             $cur_words = array($word);
         }
     }
     $lines[] = implode(' ', $cur_words);
     $cur_pos = $sx + $this->margin();
     $centre = $sy + ($ey - $sy) / 2;
     $rounded = ceil($line_height);
     $texts = array();
     foreach ($lines as $line) {
         $metrics = new BpFontMetrics($this->font(), $line, 90);
         $metrics->constrainYCentre($centre);
         $metrics->constrainLeft($cur_pos);
         $metrics->constrainRight($cur_pos + $line_height);
         $metrics->maxFontSize($font_size);
         $cur_text = new BpText($this->z, $this->textColour(), $metrics);
         $texts[] = $cur_text;
         $cur_pos += $rounded;
     }
     if ($cur_pos > $this->ex) {
         $this->ex = $cur_pos + $this->margin();
     }
     BpRectangle::render($ge);
     foreach ($texts as $cur_text) {
         $cur_text->render($ge);
     }
 }
 public function render($ge)
 {
     //BpRectangle::render($ge);
     $sx = $ge->tx($this->sx());
     $sy = $ge->ty($this->sy());
     $ex = $ge->tx($this->ex());
     $ey = $ge->ty($this->ey());
     $width = $ex - $sx - $this->margin * 2;
     $height = $ey - $sy - $this->margin * 2;
     $lines = array();
     $cur_words = array();
     $cur_width = 0;
     $cur_line = '';
     if ($this->font_size) {
         $font_size = $this->font_size;
         $line_height = BpFontMetrics::getLineHeightFromFontSize($this->font, $this->string, $this->font_size);
     } else {
         $font_size = BpFontMetrics::getFontSizeFromLineHeight($this->font, $this->string, $this->line_height);
         $line_height = $this->line_height;
     }
     $words = explode(' ', $this->string);
     foreach ($words as $word) {
         $my_words = $cur_words;
         $my_words[] = $word;
         $cur_width = BpFontMetrics::getWidth($this->font, implode(' ', $my_words), $font_size);
         if ($cur_width <= $width) {
             $cur_words[] = $word;
         } else {
             $lines[] = implode(' ', $cur_words);
             $cur_words = array($word);
         }
     }
     $lines[] = implode(' ', $cur_words);
     $cur_pos = $sy + $this->margin;
     switch ($this->alignment) {
         case BpTextBox::CENTRE:
             $constraint = $sx + ($ex - $sx) / 2;
             break;
         case BpTextBox::LEFT:
             $constraint = $sx;
             break;
         case BpTextBox::RIGHT:
             throw new Exception('unimplemented BpTextBox::RIGHT in BpTextBox::render()');
             break;
         default:
             throw new Exception('Invalid alignment: ' . $this->alignment);
             break;
     }
     $rounded = $line_height;
     //ceil($line_height);
     $texts = array();
     foreach ($lines as $line) {
         $metrics = new BpFontMetrics($this->font, $line, 0);
         switch ($this->alignment) {
             case BpTextBox::CENTRE:
                 $metrics->constrainXCentre($constraint);
                 break;
             case BpTextBox::LEFT:
                 $metrics->constrainLeft($constraint);
                 break;
             case BpTextBox::RIGHT:
                 throw new Exception('unimplemented BpTextBox::RIGHT in BpTextBox::render()');
                 break;
             default:
                 throw new Exception('Invalid alignment: ' . $this->alignment);
                 break;
         }
         $metrics->constrainTop($cur_pos);
         $metrics->constrainBottom($cur_pos + $line_height);
         $metrics->maxFontSize($font_size);
         $cur_text = new BpText($this->z, $this->text_colour, $metrics);
         $texts[] = $cur_text;
         $cur_pos += $rounded;
     }
     if ($cur_pos > $this->ey) {
         $this->ey = $cur_pos + $this->margin;
     }
     BpRectangle::render($ge);
     foreach ($texts as $cur_text) {
         $cur_text->render($ge);
     }
 }