Advertisement
Guest User

TextRenderLib

a guest
Oct 22nd, 2018
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.67 KB | None | 0 0
  1. <?php
  2.  
  3. // {{{ Thaana Text Render
  4.  
  5. /**
  6.  * Renders given Thaana text as an image, with configuration options for font, font size and color.
  7.  *
  8.  * This class currently provides the following functions:
  9.  *
  10.  * render()
  11.  * renderImage()
  12.  * setFontPath()
  13.  * setFont()
  14.  * setFontSize()
  15.  * setTextColor()
  16.  * setTextLineSpacing()
  17.  * setBgColor()
  18.  * setShadow()
  19.  *
  20.  * Simple usage:
  21.  * include('thaanaTextRender.php');
  22.  * $ttr = new ThaanaTextRender('./fonts/', 'a_waheed', 18, 'white', 0, 50, 'rgb(0,0,0)', 127, 2, '#555555', 50);
  23.  * $ttr->renderImage('swaincsc', 100, 50, 'output.png', 'png')
  24.  *
  25.  * @version Release: 1.0
  26.  */
  27. namespace App\ThaanaExtensionClasses;
  28.  
  29. class ThaanaTextRender {
  30.    
  31.     // {{{ properties
  32.    
  33.     private $fontPath = './';
  34.     private $fontFile;
  35.     private $fontSize = 12;
  36.     private $textColor = array('r' => 0, 'g' => 0, 'b' => 0);
  37.     private $textAlpha = 0;
  38.     private $textLineSpacing = 0;
  39.     private $bgColor = array('r' => 255, 'g' => 255, 'b' => 255);
  40.     private $bgAlpha = 0;
  41.     private $bgTransparent = true;
  42.     private $shadowOffset = false;
  43.     private $shadowColor = '#EBEBEB';
  44.     private $shadowAlpha = 0;
  45.     private $width;
  46.     private $align = 'center';
  47.  
  48.     // }}}
  49.    
  50.    
  51.     // {{{ __construct()
  52.    
  53.     /**
  54.      *
  55.      *
  56.      */
  57.     public function __construct($fontPath=NULL, $fontName=NULL, $fontSize=NULL, $textColor=NULL, $textAlpha=NULL, $textLineSpacing=NULL, $bgColor=NULL, $bgAlpha=NULL, $shadowOffset=NULL, $shadowColor=NULL, $shadowAlpha=NULL, $align=NULL)
  58.     {
  59.         // Initialize with specified defaults:
  60.         if (!empty($fontPath)) $this->setFontPath($fontPath);
  61.         if (!empty($fontName)) $this->setFont($fontName);
  62.         if (!empty($fontSize)) $this->setFontSize($fontSize);
  63.         if (!empty($textColor)) $this->setTextColor($textColor, $textAlpha);
  64.         if (!empty($textLineSpacing)) $this->setTextLineSpacing($textLineSpacing);
  65.         if (!empty($bgColor)) $this->setBgColor($bgColor, $bgAlpha);
  66.         if (!empty($shadowOffset)) $this->setShadow($shadowOffset, $shadowColor, $shadowAlpha);
  67.         if (!empty($align)) $this->setAlign($align);
  68.     }
  69.    
  70.     // }}}
  71.    
  72.    
  73.     // {{{ render()
  74.    
  75.     /**
  76.      * Render the given ASCII Thaana text and return image handle
  77.      *
  78.      * @param string $text          Text to render in Dhivehi as ASCII Thaana
  79.      * @param integer $width        Width of the rendered image
  80.      * @param integer $linespacing  Line spacing
  81.      * @return string               Image identifier handle
  82.      *
  83.      * @access public
  84.      */
  85.     public function render($text, $width=NULL)
  86.     {  
  87.         try
  88.         {
  89.             // Word wrap text
  90.             $lines = $this->wordWrap($text, $width);
  91.            
  92.             // Set linespacing to 1x if is not specified
  93.             $linespacing = ($this->textLineSpacing > 0) ? $this->textLineSpacing : $lines['maxheight'];
  94.  
  95.             $maxHeight = '150';
  96.  
  97.             // Calculate text width and height
  98.             $width = max($width, $lines['maxwidth']);
  99.             //$height = $linespacing * count($lines['text']);
  100.  
  101.  
  102.             $height = $maxHeight;
  103.  
  104.             // Create image
  105.             $im = imagecreatetruecolor($width, $height);
  106.            
  107.             // Setup alpha channel handling
  108.             imagesavealpha($im, true);
  109.             imagealphablending($im, true);
  110.            
  111.             // Allocate required colors
  112.             $bgColor = imagecolorallocatealpha($im, $this->bgColor['r'], $this->bgColor['g'], $this->bgColor['b'], $this->bgAlpha);
  113.             $fontColor = imagecolorallocatealpha($im, $this->textColor['r'], $this->textColor['g'], $this->textColor['b'], $this->textAlpha);
  114.            
  115.             // Set shadow color if shadow in use
  116.             if (is_numeric($this->shadowOffset))
  117.             {
  118.                 // Allocate shadow color
  119.                 $shadowColor = imagecolorallocatealpha($im, $this->shadowColor['r'], $this->shadowColor['g'], $this->shadowColor['b'], $this->shadowAlpha);
  120.             }
  121.            
  122.             // Set background color
  123.             imagefill($im, 0, 0, $bgColor);
  124.            
  125.             // Process the lines
  126.             foreach ($lines['text'] as $lineno => $line)
  127.             {
  128.                 // Reverse line
  129.                 $line = strrev($line);
  130.                
  131.                 // Calculate bounding box and line width without the new word
  132.                 $bbox = imagettfbbox($this->fontSize, 0, $this->fontFile, $line);
  133.                
  134.                 // Calculate X axis offset
  135.                 $xpos = ($width - abs($bbox[2] - $bbox[0])) - abs($bbox[0]);
  136.                
  137.                 // Calculate Y axis offset
  138.                 $ypos = ($linespacing * $lineno) + abs($bbox[7]);
  139.                
  140.                 // Render text shadow
  141.                 if ($this->shadowOffset > 0)
  142.                 {
  143.                     imagettftext($im, $this->fontSize, 0, $xpos + $this->shadowOffset,
  144.                                  $ypos + $this->shadowOffset, $shadowColor, $this->fontFile, $line
  145.                                  );
  146.                 }
  147.                
  148.                 // Render text
  149.                 imagettftext($im, $this->fontSize, 0, $xpos, $ypos, $fontColor, $this->fontFile, $line);
  150.             }
  151.        
  152.         }
  153.         catch (Exception $e)
  154.         {
  155.             // An error had occured:
  156.            
  157.             // Create a 1x1 pixel image
  158.             $im = imagecreatetruecolor(1, 1);
  159.         }
  160.        
  161.         // Return rendered image handle
  162.         return $im;
  163.     }
  164.    
  165.     // }}}
  166.    
  167.    
  168.     // {{{ renderImage()
  169.    
  170.     /**
  171.      * Render the given text and output directly or save
  172.      *
  173.      * @param string $text          Text string to render
  174.      * @param integer $width        Width of the rendered image
  175.      * @param string $filename      Filename to save the rendered image as. Set to NULL to output directly.
  176.      * @param string $imagetype     Image type. Can be 'png', 'jpg', 'jpeg' or 'gif'
  177.      * @return string               Image identifier handle
  178.      *
  179.      * @access public
  180.      */
  181.     public function renderImage($text, $width=NULL, $filename=NULL, $imagetype = 'png')
  182.     {
  183.         // Render and return image handle
  184.         $im = $this->render($text, $width);
  185.        
  186.         // Select output image type
  187.         switch ($imagetype)
  188.         {
  189.             case 'png':
  190.                 // Render as png
  191.                 header("Content-type: image/png");
  192.                 imagepng($im, $filename);
  193.                 break;
  194.            
  195.             case 'jpg':
  196.             case 'jpeg':
  197.                 // Render as jpg
  198.                 header("Content-type: image/jpeg");
  199.                 imagejpeg($im, $filename);
  200.                 break;
  201.                
  202.             case 'gif':
  203.                 // Render as gif
  204.                 header("Content-type: image/gif");
  205.                 imagegif($im, $filename);
  206.                 break;
  207.         }
  208.     }
  209.    
  210.     // }}}
  211.    
  212.    
  213.     // {{{ wordWrap()
  214.    
  215.     /**
  216.      * Word wrap the text at the given width boundary
  217.      * Returns the wrapped text as an array of lines.
  218.      * Returns max line width and max line height details
  219.      *
  220.      * @param string $text      Text to word wrap
  221.      * @param integer $width    Width boundary to word wrap
  222.      * @return array            Word wrapped line data as an array with elements [text, linewidth, lineheight]
  223.      *
  224.      * @access private
  225.      */
  226.     private function wordWrap($text, $width=NULL)
  227.     {
  228.         // Check if wrapping is necessary
  229.         if (empty($width))
  230.         {
  231.             // No width set -> no wrapping required
  232.             return explode("\r\n", $text);
  233.         }
  234.        
  235.         // Initialize variables for line data
  236.         $lines = array();
  237.         $lineno = -1;
  238.         $maxlinewidth = 0;
  239.         $maxlineheight = 0;
  240.        
  241.         // Get paragraphs
  242.         $text = explode("\n", $text);
  243.        
  244.         // Loop through paragraphs
  245.         for ($x = 0; $x < count($text); $x++)
  246.         {
  247.            
  248.             // Convert the text to an array
  249.             $word = strtok($text[$x], ' ');
  250.                        
  251.             // Begin a new line
  252.             $lines[++$lineno] = '';
  253.            
  254.             // Loop through words
  255.             while ($word !== false)
  256.             {
  257.                
  258.                 // Calculate bounding box for the current line + current word
  259.                 $bbox = imagettfbbox($this->fontSize, 0, $this->fontFile, $lines[$lineno] . $word . ' ');
  260.                
  261.                 // Calculate line width and height
  262.                 $linewidth = abs($bbox[2] - $bbox[0]);
  263.                 $lineheight = abs($bbox[7] - $bbox[1]);
  264.                
  265.                 // Check if line + word exceeds max width allowed
  266.                 if ($linewidth > $width)
  267.                 {
  268.                     // Width exceeds:
  269.                    
  270.                     // Start a new line and add current word to it
  271.                     $lines[++$lineno] = $word . ' ';
  272.                    
  273.                 }
  274.                 else
  275.                 {
  276.                     // Width ok:
  277.                    
  278.                     // Add word to current line
  279.                     $lines[$lineno] .= $word . ' ';
  280.                    
  281.                     // Store the line width/height if largest
  282.                     if ($linewidth > $maxlinewidth) $maxlinewidth = $linewidth;
  283.                     if ($lineheight > $maxlineheight) $maxlineheight = $lineheight;
  284.                 }
  285.                
  286.                 // Get next word
  287.                 $word = strtok(' ');
  288.             }
  289.         }
  290.        
  291.         // Return the wordwrapped text
  292.         return array('text' => $lines, 'maxwidth' => $maxlinewidth, 'maxheight' => $maxlineheight);
  293.     }
  294.    
  295.     // }}}
  296.    
  297.    
  298.     // {{{ setFont()
  299.    
  300.     /**
  301.      * Set the name of the font to use by checking a given list of fonts for a useable font.
  302.      * Falls back to the default if no font in the list is found.
  303.      * Expects fonts to be in the specified font path with lowercase filenames and named as given in the font list.
  304.      *
  305.      * @param string $fontNames     HTML/CSS font names list
  306.      * @param string $default       Name of font to default to in case of failure
  307.      * @return boolean              True if font set successfully, false otherwise
  308.      *
  309.      * @access public
  310.      */
  311.     public function setFont($fontNames, $default=NULL)
  312.     {
  313.         // Get the list of fonts specified
  314.         $fontNames = explode(',', $fontNames);
  315.        
  316.         // Add the default font as the last font to check
  317.         if ($default != NULL) array_push($fontNames, $default);
  318.        
  319.         // Loop through the specified list to find one that can be used
  320.         foreach ($fontNames as $fontName)
  321.         {
  322.             // Cleanup font name by removing extra whitespace and quotes
  323.             $fontName = str_replace(array('\'', '"'), '', strtolower(trim($fontName)));
  324.            
  325.             // Check if the given font exists in the fonts store
  326.             if (file_exists($this->fontPath . $fontName . '.ttf'))
  327.             {
  328.                 // Given font exists:
  329.                
  330.                 // Useable font found, set it for use
  331.                 $this->fontFile = $this->fontPath . $fontName . '.ttf';
  332.                
  333.                 return true;
  334.             }
  335.         }
  336.        
  337.         // No useable font found
  338.         return false;
  339.     }
  340.    
  341.     // }}}
  342.    
  343.    
  344.     // {{{ setFontSize()
  345.    
  346.     /**
  347.      * Set font size
  348.      *
  349.      * @param integer $size     Font size to use
  350.      * @return boolean          True if successfully set, false otherwise
  351.      *
  352.      * @access public
  353.      */
  354.     public function setFontSize($size)
  355.     {
  356.         // Check if font size is valid
  357.         if (intval($size) > 0)
  358.         {
  359.             // Font size valid
  360.            
  361.             // Save font size
  362.             $this->fontSize = intval($size);
  363.            
  364.             return true;
  365.         }
  366.            
  367.         return false;
  368.     }
  369.    
  370.     // }}}
  371.    
  372.    
  373.     // {{{ setTextColor()
  374.    
  375.     /**
  376.      * Set text color
  377.      *
  378.      * @param string $color     Text color. Can be any HTML/CSS color spec
  379.      * @param integer $alpha    Alpha value [0-127] for transparency
  380.      *
  381.      * @access public
  382.      */
  383.     public function setTextColor($color, $alpha=NULL)
  384.     {
  385.         // Set text color
  386.         $this->textColor = $this->parseColor($color);
  387.        
  388.         // Set text alpha
  389.         if (!empty($alpha)) $this->textAlpha = intval($alpha);
  390.     }
  391.    
  392.     // }}}
  393.    
  394.    
  395.     /**
  396.      * Set the line spacing for the text
  397.      *
  398.      * @param integer $spacing  Line spacing in pixels
  399.      *
  400.      * @access public
  401.      */
  402.     // {{{ setTextLineSpacing()
  403.     public function setTextLineSpacing($spacing)
  404.     {
  405.         if (!empty($spacing)) $this->textLineSpacing = intval($spacing);
  406.     }
  407.    
  408.     // }}}
  409.    
  410.    
  411.     // {{{ setFontPath()
  412.    
  413.     /**
  414.      * Set the path to where the TTF font files are stored
  415.      *
  416.      * @param string $path      Path to font files
  417.      * @return boolean          True if font path exists, false if not.
  418.      *
  419.      * @access public
  420.      */
  421.     public function setFontPath($path)
  422.     {
  423.         // Check if the path exists
  424.         if (file_exists($path))
  425.         {
  426.             // Path found:
  427.            
  428.             // Set font path
  429.             $this->fontPath = $path;
  430.            
  431.             return true;
  432.         }
  433.            
  434.         return false;
  435.     }
  436.  
  437.  
  438.     public function setAlign($alignment)
  439.     {
  440.         $this->align = 250/2;
  441.     }
  442.    
  443.     // }}}
  444.    
  445.    
  446.     // {{{ setBgColor()
  447.    
  448.     /**
  449.      * Set background color
  450.      *
  451.      * @param string $color     HTML/CSS background spec
  452.      * @param integer $alpha    Alpha value [0-127] for transparency
  453.      *
  454.      * @access public
  455.      */
  456.     public function setBgColor($color, $alpha=NULL)
  457.     {
  458.         // Set bg color
  459.         $this->bgColor = $this->parseColor($color);
  460.        
  461.         // Set bg alpha
  462.         if (!empty($alpha)) $this->bgAlpha = intval($alpha);
  463.     }
  464.    
  465.     // }}}
  466.    
  467.    
  468.     // {{{ setShadow()
  469.    
  470.     /**
  471.      * Set shadow
  472.      *
  473.      * @param integer $offset       Shadow offset
  474.      * @param string $color         Color as any HTML/CSS color spec
  475.      * @param integer $alpha        Alpha value [0-127] for transparency
  476.      *
  477.      * @access public
  478.      */
  479.     public function setShadow($offset, $color, $alpha=NULL)
  480.     {
  481.         // Set shadow offset
  482.         $this->shadowOffset = intval($offset);
  483.        
  484.         // Set shadow color
  485.         $this->shadowColor = $this->parseColor($color);
  486.        
  487.         // Set shadow alpha
  488.         if (!empty($alpha)) $this->shadowAlpha = intval($alpha);
  489.     }
  490.    
  491.     // }}}
  492.    
  493.    
  494.     // {{{ parseColor()
  495.    
  496.     /**
  497.      * Parse a string for HTML/CSS color and return RGB
  498.      *
  499.      * @param string $color     Containing color specification as RGB, hex or named colors as per HTML/CSS
  500.      * @return array            RGB color components 'r', 'g', 'b'
  501.      *
  502.      * @access private
  503.      */
  504.     private function parseColor($color)
  505.     {
  506.         // Which color format?
  507.         if (substr($color, 0, 1) == '#')
  508.         {
  509.             // Hex:
  510.            
  511.             // Extract the RGB components
  512.             $int = hexdec(substr($color, 1));
  513.             return array('r' => 0xFF & ($int >> 0x10), 'g' => 0xFF & ($int >> 0x8), 'b' => 0xFF & $int);
  514.         }
  515.         elseif (substr($color, 0, 3) == 'rgb')
  516.         {
  517.             // RGB:
  518.            
  519.             // Extract RGB components
  520.             list($r, $g, $b) = sscanf($color, 'rgb(%d,%d,%d)');
  521.            
  522.             // Return the RGB components
  523.             return array('r' => $r, 'g' => $g, 'b' => $b);
  524.         }
  525.         else
  526.         {
  527.             // Named or other:
  528.            
  529.             // W3C listed named colors required for validation
  530.             $names = array ('aqua' => '#00FFFF', 'black' => '#000000',
  531.                             'blue' => '#0000FF', 'fuchsia' => '#FF00FF',
  532.                             'gray' => '#808080', 'green' => '#008000',
  533.                             'lime' => '#00FF00', 'maroon' => '#800000',
  534.                             'navy' => '#000080', 'olive' => '#808000',
  535.                             'purple' => '#800080', 'red' => '#ff0000',
  536.                             'silver' => '#C0C0C0', 'teal' => '#008080',
  537.                             'white' => '#FFFFFF', 'yellow' => '#FFFF00'
  538.                             );
  539.            
  540.             // Check if named color is defined
  541.             if (isset($names[strtolower($color)]))
  542.             {
  543.                 // Named color defined:
  544.                
  545.                 // Recursive call to get the rgb components of the named color
  546.                 return $this->parseColor($names[strtolower($color)]);
  547.             }
  548.         }
  549.        
  550.         return array('r' => 0, 'g' => 0, 'b' => 0);
  551.     }
  552.    
  553.     // }}}
  554. }
  555. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement