private function getBoundingBox($fontSize, $fontAngle, $fontFile, $text)
    {
        $box = imagettfbbox($fontSize, $fontAngle, $fontFile, $text);

        if (!$box) {
            return false;
        }

        $minX = min([$box[0], $box[2], $box[4], $box[6]]);
        $maxX = max([$box[0], $box[2], $box[4], $box[6]]);
        $minY = min([$box[1], $box[3], $box[5], $box[7]]);
        $maxY = max([$box[1], $box[3], $box[5], $box[7]]);
        $width = ($maxX - $minX);
        $height = ($maxY - $minY);
        $left = abs($minX) + $width;
        $top = abs($minY) + $height;

        // to calculate the exact bounding box i write the text in a large image
        $img = imagecreatetruecolor($width << 2, $height << 2);
        $white = imagecolorallocate($img, 255, 255, 255);
        $black = imagecolorallocate($img, 0, 0, 0);
        imagefilledrectangle($img, 0, 0, imagesx($img), imagesy($img), $black);
        // for sure the text is completely in the image!
        imagettftext($img, $fontSize, $fontAngle, $left, $top, $white, $fontFile, $text);
        // start scanning (0=> black => empty)
        $rleft = $w4 = $width << 2;
        $rright = 0;
        $rbottom = 0;
        $rtop = $h4 = $height << 2;

        for ($x = 0; $x < $w4; $x++) {
            for ($y = 0; $y < $h4; $y++) {
                if (imagecolorat($img, $x, $y)) {
                    $rleft = min($rleft, $x);
                    $rright = max($rright, $x);
                    $rtop = min($rtop, $y);
                    $rbottom = max($rbottom, $y);
                }
            }
        }

        // destroy img and serve the result
        imagedestroy($img);

        return [
            'left' => $left - $rleft,
            'top' => $top - $rtop,
            'width' => $rright - $rleft + 1,
            'height' => $rbottom - $rtop + 1
        ];
    }