function __construct() { parent::__construct(); $this->startTime = gettimeofday(true); $message = " --- POWERED BY LIBCACA --- OLDSCHOOL TEXT EFFECTS ARE 100% PURE WIN"; $this->scroll = new Canvas(strlen($message), 1); $this->scroll->setColorAnsi(AnsiColor::WHITE, AnsiColor::TRANSPARENT); $this->scroll->putStr(0, 0, $message); $fontList = Font::getList(); $f = new Font($fontList[1]); $w = $f->getWidth() * strlen($message); $h = $f->getHeight(); $this->image = imagecreatetruecolor($w, $h); imagealphablending($this->image, false); imagesavealpha($this->image, true); $this->d = new Dither($this->image); $f->Render($this->scroll, $this->image); }
/** * @param Font $font * @param string $text * @param int $color * @param int $spacing * @throws FontException */ public function __construct(Font $font, $text, $color, $spacing = 1) { $cw = $font->getWidth(); $ch = $font->getHeight(); // no support for UTF-8 or newlines! $num_chars = strlen($text); $full_width = $cw * $num_chars + ($num_chars - 1) * $spacing; $full_height = $ch; $pixels = array_fill(0, $full_width * $full_height, 0); for ($i = 0; $i < $num_chars; ++$i) { $char = ord($text[$i]); $cox = ($cw + $spacing) * $i; $char_pixels = $font->getPixelsForCharacter($char); for ($y = 0; $y < $ch; ++$y) { for ($x = 0; $x < $cw; ++$x) { if ($char_pixels[$y * $cw + $x]) { $pixels[$full_width * $y + $cox + $x] = $color; } } } } parent::__construct($full_width, $full_height, $pixels); }
/** * @param string $character * * @return int */ private function getLetterStartPosition($character) { return (ord($character) - self::FIRST_ASCII_CHARACTER) * $this->font->getHeight() + 1 + $this->font->getCommentLines(); }
private function drawChunksWrapped ($canvas, $baseline, $left, $right, $chunks, Font $font) { global $config; $baselineStart = $baseline; $maxWidth = $right - $left; $textHeight = $font->getHeight(); $textLeading = $textHeight * $font->leadingPercent; $symbolHeight = $textHeight * ($config['card.text.symbol.height.percentage'] / 100); $symbolSpacing = $config['card.text.symbol.spacing']; $belowBaseline = 0; $xOffset = 0; $belowBaseline = 0; for ($i=0, $n=count($chunks); $i < $n; $i++) { $chunk = $chunks[$i]; if ($chunk->isSymbol) { $xOffset += $symbolSpacing; // Wrap if this symbol and any following symbols or non-whitespace text are too long. $nonWrappedChunksWidth = 0; for ($ii=$i; $ii < $n; $ii++) { $nextChunk = $chunks[$ii]; if ($nextChunk->isSymbol) { // Don't wrap in between symbols. list($symbolWidth) = $this->drawSymbol(null, 0, 0, $symbolHeight, $nextChunk->value, false, true); $nonWrappedChunksWidth += $symbolSpacing + $symbolWidth; if ($ii < $n - 1) $nonWrappedChunksWidth += $symbolSpacing; // Don't add spacing if this is the last chunk. } else { // Don't wrap in between a symbol and text (eg, when a period follows a symbol). if (preg_match('/^([^\w]*)\w/', $nextChunk->value, $matches)) { // Text starts with non-whitespace characters. Get their width. $textSize = $font->getSize($matches[0], $nextChunk->isItalic); $nonWrappedChunksWidth += $textSize['width']; } break; } } if ($xOffset + $nonWrappedChunksWidth > $maxWidth) { $xOffset = 0; $belowBaseline = 0; $baseline += $textLeading; } // Draw symbol. $symbolTop = $baseline - $symbolHeight + 1 + (($symbolHeight - $textHeight) / 2); list($symbolWidth) = $this->drawSymbol($canvas, $symbolTop, $left + $xOffset, $symbolHeight, $chunk->value, false, true, $font->getColor()); $xOffset += $symbolWidth; if ($i < $n - 1) $xOffset += $symbolSpacing; // Don't add spacing if this is the last chunk. } else { if ($chunk->newLine) { $xOffset = 0; $belowBaseline = 0; // If there last chunk was a newline with no text, then this newline is the second one in a row. Reduce the leading on the second one. $previousChunk = @$chunks[$i - 1]; if ($previousChunk && $previousChunk->newLine && $previousChunk->value == null) $baseline += $textLeading * ($config['card.text.double.spacing'] / 100); else $baseline += $textLeading; if ($chunk->value == null) continue; } $spaceSize = $font->getSize(' ', $chunk->isItalic); $spaceWidth = $spaceSize['width']; if (substr($chunk->value, 0, 1) == ' ') $xOffset += $spaceWidth; // Starts with space. // Break text into words and build an array of lines. $words = explode(' ', $chunk->value); $lines = array(); $text = ''; //$wordN = 0; foreach ($words as $word) { //$wordN++; if ($word == null || $word == '') continue; $testLine = $text; if ($text != '') $testLine .= ' '; // Space between words. $testLine .= $word; $lineSize = $font->getSize($testLine, $chunk->isItalic); if (count($lines) == 0) $lineSize['width'] += $xOffset; // Only the first line takes into account the xOffset. if ($lineSize['width'] > $maxWidth) { // Check if after a comma only one word was added. // If the codition was true then remove the previous word, start a new line and put the previous word plus current one. /*$prevWordLen = @strlen($words[$wordN-2]); if(substr($text, -$prevWordLen-2, 1) == ','){ $text = substr($text, 0, -$prevWordLen-1); $lineSize = $font->getSize($text, $chunk->isItalic); $lineSize['text'] = $text; $lines[] = $lineSize; $text = $words[$wordN-2] .' '. $word; continue; }*/ // Word doesn't fit, start a new line. $lineSize['text'] = $text; $lines[] = $lineSize; $text = $word; } else $text = $testLine; // Word fits, collect more. } // Store last line. $lineSize = $font->getSize($text, $chunk->isItalic); $lineSize['text'] = $text; $lines[] = $lineSize; $belowBaseline = max($belowBaseline, $lineSize['belowBasepoint']); // Write each line. $lineCount = count($lines); foreach ($lines as $line) { if ($canvas) $font->draw($canvas, $left + $xOffset + $line['xOffset'], $baseline, $line['text'], $chunk->isItalic); if ($lineCount > 1) { $xOffset = 0; $baseline += $textLeading; } } if ($lineCount > 1) $baseline -= $textLeading; // Stay on the last line written. $xOffset += $lineSize['width']; // Last line width. if (substr($chunk->value, -1) == ' ') $xOffset += $spaceWidth; // Ends with space. } } return array( "belowBaseline" => $belowBaseline, "lastLineWidth" => $xOffset, "height" => ($baseline - $baselineStart) + $textHeight + $belowBaseline, "lineCount" => (($baseline - $baselineStart) / $textLeading) + 1 ); }