/** * String to multiple lines * * @param string $string * @param Font $font * @param int $maxWidth * @return array */ public function stringToMultipleLines($string, Font $font, $maxWidth) { $fontBox = $font->box('我'); $maxWidth = $maxWidth - $fontBox->getWidth(); preg_match_all('/./u', $string, $words); $words = $words[0]; $lines = []; $width = 0; $offset = 0; foreach ($words as $word) { if ($this->isSbcCaseCharacter($word)) { $wordWidth = $fontBox->getWidth(); } else { try { $wordWidth = $font->box($word)->getWidth(); } catch (\Imagine\Exception\InvalidArgumentException $e) { $wordWidth = $fontBox->getWidth(); } } if ($width + $wordWidth > $maxWidth) { $width = $wordWidth; $offset++; } else { $width += $wordWidth; } if (!isset($lines[$offset])) { $lines[$offset] = ''; } $lines[$offset] .= $word; } return $lines; }
/** * Adds the text to the image. */ public function renderText() { $palette = new RGB(); $color = $palette->color('#005', 100); $font = new Font(dirname(__FILE__) . '/../assets/trebuchet_bi.ttf', 24, $color); $blocks = explode('__', $this->text); $wordWidths = array(); foreach ($blocks as $key => $block) { $blocks[$key] = preg_split('#[^a-z0-9,:\'\\.-]#i', trim($block)); foreach ($blocks[$key] as $word) { $wordWidths[] = $font->box($word)->getWidth(); } } $lineHeight = 45; $maxRatio = 0; $result = array(); $space = $font->box('-')->getWidth(); $stepWidth = 25; for ($maxWidth = floor(max($wordWidths) / $stepWidth) * $stepWidth; $maxWidth <= 375; $maxWidth += $stepWidth) { $wordIndex = 0; $lines = array(); $maxLineWidth = 0; foreach ($blocks as $block) { $lines[] = ''; $lineWidth = 0; foreach ($block as $word) { if ($lineWidth + $wordWidths[$wordIndex] > $maxWidth && $lines[count($lines) - 1] != '') { $lines[] = ''; $lineWidth = 0; } $lines[count($lines) - 1] .= $word . ' '; $lineWidth += $wordWidths[$wordIndex] + $space; if ($lineWidth - $space > $maxLineWidth) { $maxLineWidth = $lineWidth - $space; } ++$wordIndex; } } $min = min(count($lines) * $lineHeight, $maxLineWidth); $max = max(count($lines) * $lineHeight, $maxLineWidth); $ratio = $min / $max; if ($ratio > $maxRatio) { $result = $lines; $maxRatio = $ratio; } } $y = $this->image->getSize()->getHeight() / 2 - $lineHeight * (count($result) / 2) + 4; foreach ($result as $line) { $box = $font->box(trim($line)); $this->image->draw()->text(trim($line), $font, new Point($this->image->getSize()->getWidth() / 2 - $box->getWidth() / 2, $y)); $y += $lineHeight; } }