[ 'bg_color' => [245, 245, 245], 'text_color' => [50, 50, 50], 'border_color' => [200, 200, 200], 'padding' => 20, 'rounded' => 15, 'font_size' => 14, 'max_width' => 600, 'line_height' => 20, 'font' => __DIR__ . '/fonts/arial.ttf', // Adjust path as needed ], 'modern' => [ 'bg_color' => [66, 133, 244], 'text_color' => [255, 255, 255], 'border_color' => [59, 120, 220], 'padding' => 20, 'rounded' => 20, 'font_size' => 14, 'max_width' => 600, 'line_height' => 20, 'font' => __DIR__ . '/fonts/arial.ttf', // Adjust path as needed ], 'retro' => [ 'bg_color' => [255, 204, 102], 'text_color' => [51, 51, 51], 'border_color' => [204, 153, 0], 'padding' => 20, 'rounded' => 5, 'font_size' => 14, 'max_width' => 600, 'line_height' => 20, 'font' => __DIR__ . '/fonts/arial.ttf', // Adjust path as needed ], 'minimal' => [ 'bg_color' => [255, 255, 255], 'text_color' => [0, 0, 0], 'border_color' => [220, 220, 220], 'padding' => 15, 'rounded' => 0, 'font_size' => 14, 'max_width' => 600, 'line_height' => 20, 'font' => __DIR__ . '/fonts/arial.ttf', // Adjust path as needed ], ]; // Use default style if specified style doesn't exist if (!isset($styles[$style])) { $style = 'default'; } // Get style settings $config = $styles[$style]; // Check for fonts directory and create if it doesn't exist $fontsDir = __DIR__ . '/fonts'; if (!is_dir($fontsDir)) { mkdir($fontsDir, 0755, true); } // Fallback to a built-in font if the specified font file doesn't exist if (!file_exists($config['font'])) { // Try to find any TTF font in the fonts directory $foundFont = false; if (is_dir($fontsDir)) { $fontFiles = glob($fontsDir . '/*.ttf'); if (!empty($fontFiles)) { $config['font'] = $fontFiles[0]; $foundFont = true; } } // If no TTF font found, use built-in font if (!$foundFont) { $config['use_builtin_font'] = true; } } // Create a temporary image to calculate text dimensions $tempImage = imagecreatetruecolor(100, 100); $textColor = imagecolorallocate($tempImage, $config['text_color'][0], $config['text_color'][1], $config['text_color'][2]); // Word wrap the text $words = explode(' ', $text); $lines = []; $currentLine = ''; $maxWidth = $config['max_width'] - (2 * $config['padding']); foreach ($words as $word) { $testLine = $currentLine . ' ' . $word; $testLine = ltrim($testLine); // Remove leading space // Calculate width using built-in or TTF font if (isset($config['use_builtin_font'])) { $textWidth = imagefontwidth(5) * strlen($testLine); } else { $bbox = imagettfbbox($config['font_size'], 0, $config['font'], $testLine); $textWidth = $bbox[2] - $bbox[0]; } if ($textWidth > $maxWidth && $currentLine !== '') { $lines[] = $currentLine; $currentLine = $word; } else { $currentLine = $testLine; } } if ($currentLine !== '') { $lines[] = $currentLine; } // Calculate image dimensions $lineCount = count($lines); if (isset($config['use_builtin_font'])) { $lineHeight = imagefontheight(5); $textHeight = $lineHeight * $lineCount; // Find the longest line to determine width $textWidth = 0; foreach ($lines as $line) { $lineWidth = imagefontwidth(5) * strlen($line); $textWidth = max($textWidth, $lineWidth); } } else { $lineHeight = $config['line_height']; $textHeight = $lineHeight * $lineCount; // Find the longest line to determine width $textWidth = 0; foreach ($lines as $line) { $bbox = imagettfbbox($config['font_size'], 0, $config['font'], $line); $lineWidth = $bbox[2] - $bbox[0]; $textWidth = max($textWidth, $lineWidth); } } // Add padding to dimensions $imgWidth = min($config['max_width'], $textWidth + (2 * $config['padding'])); $imgHeight = $textHeight + (2 * $config['padding']); // Create the bubble image $image = imagecreatetruecolor($imgWidth, $imgHeight); // Allocate colors $bgColor = imagecolorallocate($image, $config['bg_color'][0], $config['bg_color'][1], $config['bg_color'][2]); $borderColor = imagecolorallocate($image, $config['border_color'][0], $config['border_color'][1], $config['border_color'][2]); $textColor = imagecolorallocate($image, $config['text_color'][0], $config['text_color'][1], $config['text_color'][2]); // Fill background imagefill($image, 0, 0, $bgColor); // Draw rounded rectangle (if rounded corners are requested) if ($config['rounded'] > 0) { // Draw filled rectangle imagefilledrectangle($image, 0, 0, $imgWidth - 1, $imgHeight - 1, $bgColor); // Draw rounded corners - basic simulation for rounded corners // This could be improved with proper arc drawing $r = $config['rounded']; // Top left corner imagefilledarc($image, $r, $r, $r * 2, $r * 2, 180, 270, $bgColor, IMG_ARC_PIE); // Top right corner imagefilledarc($image, $imgWidth - $r - 1, $r, $r * 2, $r * 2, 270, 360, $bgColor, IMG_ARC_PIE); // Bottom left corner imagefilledarc($image, $r, $imgHeight - $r - 1, $r * 2, $r * 2, 90, 180, $bgColor, IMG_ARC_PIE); // Bottom right corner imagefilledarc($image, $imgWidth - $r - 1, $imgHeight - $r - 1, $r * 2, $r * 2, 0, 90, $bgColor, IMG_ARC_PIE); // Draw border imagerectangle($image, 0, 0, $imgWidth - 1, $imgHeight - 1, $borderColor); } else { // Draw simple rectangle imagefilledrectangle($image, 0, 0, $imgWidth - 1, $imgHeight - 1, $bgColor); imagerectangle($image, 0, 0, $imgWidth - 1, $imgHeight - 1, $borderColor); } // Draw text $y = $config['padding']; foreach ($lines as $line) { if (isset($config['use_builtin_font'])) { // Use built-in font (less nice but always available) imagestring($image, 5, $config['padding'], $y, $line, $textColor); $y += imagefontheight(5); } else { // Use TrueType font (nicer but requires font file) imagettftext($image, $config['font_size'], 0, $config['padding'], $y + $config['font_size'], $textColor, $config['font'], $line); $y += $lineHeight; } } // Output the image imagepng($image); // Clean up imagedestroy($image); imagedestroy($tempImage);