Função de calculo de largura da uma string de acordo com o tamanho da fonte
@copyright http://n4.nabble.com/Finding-width-of-a-drawText-Text-in-Zend-Pdf-td677978.html
@param $string
@param $font
@param $fontSize
10457
private function widthForStringUsingFontSize($string, $font, $fontSize = 8)
    {
        @$drawingString = \iconv('', 'UTF-16BE', $string);
        $characters = array();
        for ($i = 0; $i < strlen($drawingString); $i++) {
            $characters[] = (ord($drawingString[$i++]) << 8) | ord($drawingString[$i]);
        }
        $glyphs = $font->glyphNumbersForCharacters($characters);
        $widths = $font->widthsForGlyphs($glyphs);
        $stringWidth = (array_sum($widths) / $font->getUnitsPerEm()) * $fontSize;

        return $stringWidth;
    }
867862
public function getWrappedText($size, $angle, $fontface, $string, $width = 100)
    {
        $str = '';
        $words = explode(' ', $string);

        foreach ($words as $word) {
            $testStr = $str . ' ' . $word;
            $box = imagettfbbox($size, $angle, $fontface, $testStr);

            if ($box[2] > $width) {
                $str .= ($str == '' ? '' : "\n") . $word;
            } else {
                $str .= ($str == '' ? '' : ' ') . $word;
            }
        }

        $this->string = $str;
        $lines = explode("\n", $str);

        return $lines;
    }
86146
public void showTextKerned(String text) {
        if (state.fontDetails == null)
            throw new NullPointerException("Font and size must be set before writing any text");
        BaseFont bf = state.fontDetails.getBaseFont();
        if (bf.hasKernPairs())
            showText(getKernArray(text, bf));
        else
            showText(text);
    }
1264774
function get_font_height($font, $size) {
		if (!$font) {
			$fontFamily = $this->_pdf->getFontFamily();
			$fontStyle = $this->_pdf->getFontStyle();
		}
		else {
			$fontdata = $this->_get_font($font);
			$fontFamily = $fontdata['family'];
			$fontStyle = $fontdata['style'];
			$this->_pdf->SetFont($fontFamily, $fontStyle, $size, $font);
		}
		if (strpos($fontStyle, 'B') !== false) {
			$scale = self::FONT_HEIGHT_SCALE_BOLD;
		}
		else {
			$scale = self::FONT_HEIGHT_SCALE_NORMAL;
		}
		$result = $scale * $size;
		//Helpers::dompdf_debug("trace", "(". basename($font) .", $size): returns $result");
		return $result;
	}
44517
def text_width(string, font_name, font_size):
    """"""
    return stringWidth(string, fontName=font_name, fontSize=font_size)
770266
protected function billetSetFont($font)
    {
        $f = static::FONTS[$font];
        $this->SetFont($f[0], $f[1], $f[2]);
        if (count($f) > 3) {
            $this->SetTextColor(...$f[3]);
        }
    }
347578
private function generateImage($string, $size, $color)
	{
		$this->setString($string);
		$this->setSize($size);

		if ($this->fontPath === null)
		{
			$this->setFontPath(__DIR__ . '/fonts/OpenSans-Regular.ttf');
		}

		// Prepare the image
		$image = imagecreatetruecolor($this->pixelRatio * 5, $this->pixelRatio * 5);
		$background = imagecolorallocate($image, 0, 0, 0);

		// Prepage the color
		if (null !== $color)
		{
			$this->setColor($color);
		}
		$color = imagecolorallocate($image, $this->color[0], $this->color[1], $this->color[2]);
		imagefilledrectangle($image, 0, 0, $this->size, $this->size, $color);

		// Allocate A Color For The Text
		$white = imagecolorallocate($image, 255, 255, 255);

		$rnd = ceil($this->size / 20);

		$fontsize = round($this->size * 0.4); //ceil(($this->size / 3) + $rnd);

		$tb = imagettfbbox($fontsize, 0, $this->getFontPath(), $string);

		// Calculate x baseline
		/*if ($tb[0] >= -1)
		{
			$tb['x'] = abs($tb[0] + 1) * -1;
		}
		else
		{
			$tb['x'] = abs($tb[0] + 2);
		}

		// Calculate actual text width
		$tb['width'] = abs($tb[2] - $tb[0]);
		if ($tb[0] < -1)
		{
			$tb['width'] = abs($tb[2]) + abs($tb[0]) - 1;
		}

		// Calculate y baseline
		$tb['y'] = abs($tb[5] + 1);

		// Calculate actual text height
		$tb['height'] = abs($tb[7]) - abs($tb[1]);
		if ($tb[3] > 0)
		{
			$tb['height'] = abs($tb[7] - $tb[1]) - 1;
		}*/

		// Horizontally centr the text
		$x = ceil((($this->size - $tb[2]) / 2) - $rnd);
		//$x = ceil(($this->size - $tb['width']) / 2);

		// Vertically center the text
		$y = ceil(($this->size - $tb[7] - $rnd) / 2);
		//$y = ceil(($this->size - $tb['height']) / 2);
		//$y = $this->size - $y;

		// Print Text On Image
		imagettftext($image, $fontsize, 0, $x, $y, $white, $this->getFontPath(), $string);

		imagepng($image);
	}
1233602
protected function drawWord()
    {
        $ratio = ($this->font_ratio) ? $this->font_ratio : 0.4;

        if ((float)$ratio < 0.1 || (float)$ratio >= 1) {
            $ratio = 0.4;
        }

        if (!is_readable($this->ttfFile())) {
            // this will not catch missing fonts after the first!
            $this->perturbation = 0;
            imagestring($this->im, 4, 10, ($this->image_height / 2) - 5, 'Failed to load TTF font file!', $this->gdtextcolor);

            return ;
        }

        if ($this->perturbation > 0) {
            $width     = $this->image_width * $this->iscale;
            $height    = $this->image_height * $this->iscale;
            $font_size = $height * $ratio;
            $im        = &$this->tmpimg;
            $scale     = $this->iscale;
        } else {
            $height    = $this->image_height;
            $width     = $this->image_width;
            $font_size = $this->image_height * $ratio;
            $im        = &$this->im;
            $scale     = 1;
        }

        $captcha_text = $this->code_display;

        if ($this->use_random_spaces && $this->strpos($captcha_text, ' ') === false) {
            if (mt_rand(1, 100) % 5 > 0) { // ~20% chance no spacing added
                $index  = mt_rand(1, $this->strlen($captcha_text) -1);
                $spaces = mt_rand(1, 3);

                // in general, we want all characters drawn close together to
                // prevent easy segmentation by solvers, but this adds random
                // spacing between two groups to make character positioning
                // less normalized.

                $captcha_text = sprintf(
                    '%s%s%s',
                    $this->substr($captcha_text, 0, $index),
                    str_repeat(' ', $spaces),
                    $this->substr($captcha_text, $index)
                );
            }
        }

        $fonts    = array();  // list of fonts corresponding to each char $i
        $angles   = array();  // angles corresponding to each char $i
        $distance = array();  // distance from current char $i to previous char
        $dims     = array();  // dimensions of each individual char $i
        $txtWid   = 0;        // width of the entire text string, including spaces and distances

        // Character positioning and angle

        $angle0 = mt_rand(10, 20);
        $angleN = mt_rand(-20, 10);

        if ($this->use_text_angles == false) {
            $angle0 = $angleN = $step = 0;
        }

        if (mt_rand(0, 99) % 2 == 0) {
            $angle0 = -$angle0;
        }
        if (mt_rand(0, 99) % 2 == 1) {
            $angleN = -$angleN;
        }

        $step   = abs($angle0 - $angleN) / ($this->strlen($captcha_text) - 1);
        $step   = ($angle0 > $angleN) ? -$step : $step;
        $angle  = $angle0;

        for ($c = 0; $c < $this->strlen($captcha_text); ++$c) {
            $font     = $this->ttfFile(); // select random font from list for this character
            $fonts[]  = $font;
            $angles[] = $angle;  // the angle of this character
            $dist     = mt_rand(-2, 0) * $scale; // random distance between this and next character
            $distance[] = $dist;
            $char     = $this->substr($captcha_text, $c, 1); // the character to draw for this sequence

            $dim = $this->getCharacterDimensions($char, $font_size, $angle, $font); // calculate dimensions of this character

            $dim[0] += $dist;   // add the distance to the dimension (negative to bring them closer)
            $txtWid += $dim[0]; // increment width based on character width

            $dims[] = $dim;

            $angle += $step; // next angle

            if ($angle > 20) {
                $angle = 20;
                $step  = $step * -1;
            } elseif ($angle < -20) {
                $angle = -20;
                $step  = -1 * $step;
            }
        }

        $nextYPos = function($y, $i, $step) use ($height, $scale, $dims) {
            static $dir = 1;

            if ($y + $step + $dims[$i][2] + (10 * $scale) > $height) {
                $dir = 0;
            } elseif ($y - $step - $dims[$i][2] < $dims[$i][1] + $dims[$i][2] + (5 * $scale)) {
                $dir = 1;
            }

            if ($dir) {
                $y += $step;
            } else {
                $y -= $step;
            }

            return $y;
        };

        $cx = floor($width / 2 - ($txtWid / 2));
        $x  = mt_rand(5 * $scale, max($cx * 2 - (5 * $scale), 5 * $scale));

        if ($this->use_random_baseline) {
            $y = mt_rand($dims[0][1], $height - 10);
        } else {
            $y = ($height / 2 + $dims[0][1] / 2 - $dims[0][2]);
        }

        $st = $scale * mt_rand(5, 10);

        for ($c = 0; $c < $this->strlen($captcha_text); ++$c) {
            $font  = $fonts[$c];
            $char  = $this->substr($captcha_text, $c, 1);
            $angle = $angles[$c];
            $dim   = $dims[$c];

            if ($this->use_random_baseline) {
                $y = $nextYPos($y, $c, $st);
            }

            imagettftext(
                $im,
                $font_size,
                $angle,
                (int)$x,
                (int)$y,
                $this->gdtextcolor,
                $font,
                $char
            );

            if ($this->use_random_boxes && strlen(trim($char)) && mt_rand(1,100) % 5 == 0) {
                imagesetthickness($im, 3);
                imagerectangle($im, $x, $y - $dim[1] + $dim[2], $x + $dim[0], $y + $dim[2], $this->gdtextcolor);
            }

            if ($c == ' ') {
                $x += $dim[0];
            } else {
                $x += $dim[0] + $distance[$c];
            }
        }

        // DEBUG
        //$this->im = $im;
        //$this->output();
    }
353667
@Override protected void resizeDynamicText() {
        double maxWidth = unitText.isVisible() ? width - size * 0.275 : width - size * 0.1;
        double fontSize = 0.24 * size;
        valueText.setFont(Fonts.latoRegular(fontSize));
        if (valueText.getLayoutBounds().getWidth() > maxWidth) { Helper.adjustTextSize(valueText, maxWidth, fontSize); }

        maxWidth = width - size * 0.55;
        fontSize = size * 0.18;
        deviationText.setFont(Fonts.latoRegular(fontSize));
        if (deviationText.getLayoutBounds().getWidth() > maxWidth) { Helper.adjustTextSize(deviationText, maxWidth, fontSize); }

        maxWidth = width - size * 0.9;
        fontSize = size * 0.12;
        deviationUnitText.setFont(Fonts.latoRegular(fontSize));
        if (deviationUnitText.getLayoutBounds().getWidth() > maxWidth) { Helper.adjustTextSize(deviationUnitText, maxWidth, fontSize); }
    }
841967
private int stringWidth(FontMetrics fm, String text)
    {
        int w = fm.stringWidth(text);
        if (wordSpacing != null)
        {
            //count spaces and add
            float add = 0.0f;
            for (int i = 0; i < text.length(); i++)
            {
                if (text.charAt(i) == ' ')
                    add += wordSpacing;
            }
            w = Math.round(w + add);
        }
        return w;
    }
24749
public function resizeTable(int $maxSize = null) {
        if ($maxSize !== null) {
            $this->maxSize = $maxSize;
        }

        while ($this->size > $this->maxSize) {
            list($name, $value) = \array_pop($this->headers);
            $this->size -= 32 + \strlen($name) + \strlen($value);
        }
    }
87904
public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font $font = null, $rotation = 0)
    {
        $fontName = $font->getName();
        $fontSize = $font->getSize();

        // Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size.
        switch ($fontName) {
            case 'Calibri':
                // value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font.
                $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText));
                $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size
                break;

            case 'Arial':
                // value 7 was found via interpolation by inspecting real Excel files with Arial 10 font.
//                $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText));
                // value 8 was set because of experience in different exports at Arial 10 font.
                $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText));
                $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size
                break;

            case 'Verdana':
                // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font.
                $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText));
                $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size
                break;

            default:
                // just assume Calibri
                $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText));
                $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size
                break;
        }

        // Calculate approximate rotated column width
        if ($rotation !== 0) {
            if ($rotation == -165) {
                // stacked text
                $columnWidth = 4; // approximation
            } else {
                // rotated text
                $columnWidth = $columnWidth * cos(deg2rad($rotation))
                                + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation
            }
        }

        // pixel width is an integer
        return (int) $columnWidth;
    }
1169813
function setTextStyle(ctx, fontSize) {
  ctx.font = `${fontSize}px Helvetica,Arial,sans-serif`;
  ctx.fillStyle = '#000';
  ctx.textBaseline = 'top';
  ctx.textAlign = 'center';
}
601511
public function setFont($font) {
        if ($font === null) {
            throw new CINArgumentException('Font cannot be null.', 'font');
        }

        $this->font = clone $font;
        $this->font->setText($this->text);
        $this->font->setRotationAngle($this->rotationAngle);
        $this->font->setBackgroundColor($this->backgroundColor);
        $this->font->setForegroundColor($this->foregroundColor);
    }
975225
@Override protected void resizeDynamicText() {
        double maxWidth = unitText.isVisible() ? width - size * 0.275 : width - size * 0.1;
        double fontSize = size * 0.24;
        valueText.setFont(Fonts.latoRegular(fontSize));
        if (valueText.getLayoutBounds().getWidth() > maxWidth) { Helper.adjustTextSize(valueText, maxWidth, fontSize); }
    }
521782
function loadFont (fontFace, callback) {
  var defaultNode;
  var testNode;
  var checkFont;

  // See if we've previously loaded it.
  if (_loadedFonts[fontFace.id]) {
    return callback(null);
  }

  // See if we've previously failed to load it.
  if (_failedFonts[fontFace.id]) {
    return callback(_failedFonts[fontFace.id]);
  }

  // System font: assume already loaded.
  if (!fontFace.url) {
    return callback(null);
  }

  // Font load is already in progress:
  if (_pendingFonts[fontFace.id]) {
    _pendingFonts[fontFace.id].callbacks.push(callback);
    return;
  }

  // Create the test <span>'s for measuring.
  defaultNode = createTestNode('Helvetica', fontFace.attributes);
  testNode = createTestNode(fontFace.family, fontFace.attributes);
  document.body.appendChild(testNode);
  document.body.appendChild(defaultNode);

  _pendingFonts[fontFace.id] = {
    startTime: Date.now(),
    defaultNode: defaultNode,
    testNode: testNode,
    callbacks: [callback]
  };

  // Font watcher
  checkFont = function () {
    var currWidth = testNode.getBoundingClientRect().width;
    var defaultWidth = defaultNode.getBoundingClientRect().width;
    var loaded = currWidth !== defaultWidth;

    if (loaded) {
      handleFontLoad(fontFace, null);
    } else {
      // Timeout?
      if (Date.now() - _pendingFonts[fontFace.id].startTime >= kFontLoadTimeout) {
        handleFontLoad(fontFace, true);
      } else {
        requestAnimationFrame(checkFont);
      }
    }
  };

  // Start watching
  checkFont();
}
1371948
function getTextWidth( $size, $text )
    {
        // this function should not change any of the settings, though it will need to
        // track any directives which change during calculation, so copy them at the start
        // and put them back at the end.
        $this->pushTextState( $this->currentTextState );

        if (!$this->numFonts)
        {
            $this->selectFont('./fonts/Helvetica');
        }

        // converts a number or a float to a string so it can get the width
        $text = "$text";
        // hmm, this is where it all starts to get tricky - use the font information to
        // calculate the width of each character, add them up and convert to user units
        $w = 0;
        $len = strlen( $text );
        $cf = $this->currentFont;
        for ( $i = 0; $i < $len; $i++ )
        {
            $f = 1;
            $directiveArray = $this->PRVTcheckTextDirective( $text, $i, $f );
            $directive = $directiveArray['directive'];
            if ( $directive )
            {
                if ($f)
                {
                    $this->setCurrentFont();
                    $cf = $this->currentFont;
                }
                $i = $i + $directive-1;
            }
            else
            {
                $char = ord( $text[$i] );
                if ( isset($this->fonts[$cf]['differences'][$char] ) )
                {
                    // then this character is being replaced by another
                    $name = $this->fonts[$cf]['differences'][$char];
                    if ( isset($this->fonts[$cf]['C'][$name]['WX'] ) )
                    {
                        $w += $this->fonts[$cf]['C'][$name]['WX'];
                    }
                }
                else if ( isset($this->fonts[$cf]['C'][$char]['WX'] ) )
                {
                    $w += $this->fonts[$cf]['C'][$char]['WX'];
                }
                else
                {
                    $w += 700;
                }
            }
        }

        $this->popTextState();
        $this->setCurrentFont();

        return $w*$size/1000;
    }