You are here

protected function TextToWrapper::wrapText in Image Effects 8

Same name and namespace in other branches
  1. 8.3 src/Plugin/ImageToolkit/Operation/gd/TextToWrapper.php \Drupal\image_effects\Plugin\ImageToolkit\Operation\gd\TextToWrapper::wrapText()
  2. 8.2 src/Plugin/ImageToolkit/Operation/gd/TextToWrapper.php \Drupal\image_effects\Plugin\ImageToolkit\Operation\gd\TextToWrapper::wrapText()

Wrap text for rendering at a given width.

Parameters

string $text: Text string in UTF-8 encoding.

int $font_size: Font size.

string $font_uri: URI of the TrueType font to use.

int $maximum_width: Maximum width allowed for each line.

Return value

string Text string, with newline characters to separate each line.

1 call to TextToWrapper::wrapText()
TextToWrapper::execute in src/Plugin/ImageToolkit/Operation/gd/TextToWrapper.php
Performs the actual manipulation on the image.

File

src/Plugin/ImageToolkit/Operation/gd/TextToWrapper.php, line 376

Class

TextToWrapper
Defines GD Text Overlay text-to-wrapper operation.

Namespace

Drupal\image_effects\Plugin\ImageToolkit\Operation\gd

Code

protected function wrapText($text, $font_size, $font_uri, $maximum_width) {

  // State variables for the search interval.
  $end = 0;
  $begin = 0;
  $fit = $begin;

  // Note: we count in bytes for speed reasons, but maintain character
  // boundaries.
  while (TRUE) {

    // Find the next wrap point (always after trailing whitespace).
    $match = [];
    if (TextUtility::unicodePregMatch('/[' . TextUtility::PREG_CLASS_PUNCTUATION . '][' . TextUtility::PREG_CLASS_SEPARATOR . ']*|[' . TextUtility::PREG_CLASS_SEPARATOR . ']+/u', $text, $match, PREG_OFFSET_CAPTURE, $end)) {
      $end = $match[0][1] + Unicode::strlen($match[0][0]);
    }
    else {
      $end = Unicode::strlen($text);
    }

    // Fetch text, removing trailing white-space, and measure it.
    $line = preg_replace('/[' . TextUtility::PREG_CLASS_SEPARATOR . ']+$/u', '', Unicode::substr($text, $begin, $end - $begin));
    $width = $this
      ->getTextWidth($line, $font_size, $font_uri);

    // See if line extends past the available space.
    if ($width > $maximum_width) {

      // If this is the first word, we need to truncate it.
      if ($fit == $begin) {

        // Cut off letters until it fits.
        while (Unicode::strlen($line) > 0 && $width > $maximum_width) {
          $line = Unicode::substr($line, 0, -1);
          $width = $this
            ->getTextWidth($line, $font_size, $font_uri);
        }

        // If no fit was found, the image is too narrow.
        $fit = Unicode::strlen($line) ? $begin + Unicode::strlen($line) : $end;
      }

      // We have a valid fit for the next line. Insert a line-break and reset
      // the search interval.
      if (Unicode::substr($text, $fit - 1, 1) == ' ') {
        $first_part = Unicode::substr($text, 0, $fit - 1);
      }
      else {
        $first_part = Unicode::substr($text, 0, $fit);
      }
      $last_part = Unicode::substr($text, $fit);
      $text = $first_part . "\n" . $last_part;
      $begin = ++$fit;
      $end = $begin;
    }
    else {

      // We can fit this text. Wait for now.
      $fit = $end;
    }
    if ($end == Unicode::strlen($text)) {

      // All text fits. No more changes are needed.
      break;
    }
  }
  return $text;
}