Revision [7079]

This is an old revision of FontActionInfo made by OnkelJonas on 2005-04-03 03:41:13.

 

This action takes text and renders it with a font on the server.
The script is from A List Apart/Stewart Rosenberger - I just did some crude hacks to make it work as an action (my PHP skills are extremely limited).

An entry would look like
{{font text="The text goes here" font="FontNameHere"}}

The script has variables for:

It is still very rough, but it works.
It passes the image text as both the alt and title tags - I believe this will satisfy accesibility requirements.
It accepts .ttf (TrueType) and .otf (OpenType) font files.


TODO:

The action:
  1. <?php
  2. /*
  3.     "font" action
  4.  
  5.     Parameters:
  6.         text        - The text to convert, also used for alt and title attributes
  7.         link        - The font to use
  8.  
  9. */
  10.  
  11. if (is_array($vars))
  12. {
  13.     foreach ($vars as $param => $value)
  14.     {
  15.         if ($param == 'text') {$text=$this->htmlspecialchars_ent($vars['text']);}
  16.         if ($param == 'font') {$font=$this->htmlspecialchars_ent($vars['font']);}
  17.     }
  18. }
  19.  
  20. $output = "<img src=\"/fonts/".$font.".php?text=".$text."\" alt=\"".$text."\" title=\"".$text."\" />";
  21.  
  22.  
  23. // link?
  24. if ($link = $vars['link'])
  25. {
  26.     $output = $this->Link($link, "", $output, 1, 0, 0);
  27. }
  28.  
  29. $output = $this->ReturnSafeHTML($output);
  30. print($output);
  31.  
  32. ?>


The rendering script:
  1. <?php
  2. /*
  3.     Dynamic Heading Generator
  4.     By Stewart Rosenberger
  5.     http://www.stewartspeak.com/headings/    
  6.  
  7.     This script generates PNG images of text, written in
  8.     the font/size that you specify. These PNG images are passed
  9.     back to the browser. Optionally, they can be cached for later use.
  10.     If a cached image is found, a new image will not be generated,
  11.     and the existing copy will be sent to the browser.
  12.  
  13.     Additional documentation on PHP's image handling capabilities can
  14.     be found at http://www.php.net/image/    
  15. */
  16.  
  17.  
  18. $font_file  = '/path/to/font' ;
  19. $font_size  = 50 ;
  20. $font_color = '#000000' ;
  21. $background_color = '#ffffff' ;
  22. $transparent_background  = true ;
  23. $cache_images = true ;
  24. $cache_folder = '/path/to/cache' ;
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32. /*
  33.   ---------------------------------------------------------------------------
  34.    For basic usage, you should not need to edit anything below this comment.
  35.    If you need to further customize this script's abilities, make sure you
  36.    are familiar with PHP and its image handling capabilities.
  37.   ---------------------------------------------------------------------------
  38. */
  39.  
  40. $mime_type = 'image/png' ;
  41. $extension = '.png' ;
  42. $send_buffer_size = 4096 ;
  43.  
  44. // check for GD support
  45. if(!function_exists('ImageCreate'))
  46.     fatal_error('Error: Server does not support PHP image generation') ;
  47.  
  48. // clean up text
  49. if(empty($_GET['text']))
  50.     fatal_error('Error: No text specified.') ;
  51.    
  52. $text = $_GET['text'] ;
  53.     $text = stripslashes($text) ;
  54. $text = javascript_to_html($text) ;
  55.  
  56. // look for cached copy, send if it exists
  57. $hash = md5(basename($font_file) . $font_size . $font_color .
  58.             $background_color . $transparent_background . $text) ;
  59. $cache_filename = $cache_folder . '/' . $hash . $extension ;
  60. if($cache_images && ($file = @fopen($cache_filename,'rb')))
  61. {
  62.     header('Content-type: ' . $mime_type) ;
  63.     while(!feof($file))
  64.         print(($buffer = fread($file,$send_buffer_size))) ;
  65.     fclose($file) ;
  66.     exit ;
  67. }
  68.  
  69. // check font availability
  70. $font_found = is_readable($font_file) ;
  71. if(!$font_found)
  72. {
  73.     fatal_error('Error: The server is missing the specified font.') ;
  74. }
  75.  
  76. // create image
  77. $background_rgb = hex_to_rgb($background_color) ;
  78. $font_rgb = hex_to_rgb($font_color) ;
  79. $dip = get_dip($font_file,$font_size) ;
  80. $box = @ImageTTFBBox($font_size,0,$font_file,$text) ;
  81. $image = @ImageCreate(abs($box[2]-$box[0]),abs($box[5]-$dip)) ;
  82. if(!$image || !$box)
  83. {
  84.     fatal_error('Error: The server could not create this heading image.') ;
  85. }
  86.  
  87. // allocate colors and draw text
  88. $background_color = @ImageColorAllocate($image,$background_rgb['red'],
  89.     $background_rgb['green'],$background_rgb['blue']) ;
  90. $font_color = ImageColorAllocate($image,$font_rgb['red'],
  91.     $font_rgb['green'],$font_rgb['blue']) ;  
  92. ImageTTFText($image,$font_size,0,-$box[0],abs($box[5]-$box[3])-$box[1],
  93.     $font_color,$font_file,$text) ;
  94.  
  95. // set transparency
  96. if($transparent_background)
  97.     ImageColorTransparent($image,$background_color) ;
  98.  
  99. header('Content-type: ' . $mime_type) ;
  100. ImagePNG($image) ;
  101.  
  102. // save copy of image for cache
  103. if($cache_images)
  104. {
  105.     @ImagePNG($image,$cache_filename) ;
  106. }
  107.  
  108. ImageDestroy($image) ;
  109.  
  110.  
  111. /*
  112.     try to determine the "dip" (pixels dropped below baseline) of this
  113.     font for this size.
  114. */
  115. function get_dip($font,$size)
  116. {
  117.     $test_chars = 'abcdefghijklmnopqrstuvwxyz' .
  118.                   'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
  119.                   '1234567890' .
  120.                   '!@#$%^&*()\'"\\/;.,`~<>[]{}-+_-=' ;
  121.     $box = @ImageTTFBBox($size,0,$font,$test_chars) ;
  122.     return $box[3] ;
  123. }
  124.  
  125.  
  126. /*
  127.     attempt to create an image containing the error message given.
  128.     if this works, the image is sent to the browser. if not, an error
  129.     is logged, and passed back to the browser as a 500 code instead.
  130. */
  131. function fatal_error($message)
  132. {
  133.     // send an image
  134.     if(function_exists('ImageCreate'))
  135.     {
  136.         $width = ImageFontWidth(5) * strlen($message) + 10 ;
  137.         $height = ImageFontHeight(5) + 10 ;
  138.         if($image = ImageCreate($width,$height))
  139.         {
  140.             $background = ImageColorAllocate($image,255,255,255) ;
  141.             $text_color = ImageColorAllocate($image,0,0,0) ;
  142.             ImageString($image,5,5,5,$message,$text_color) ;    
  143.             header('Content-type: image/png') ;
  144.             ImagePNG($image) ;
  145.             ImageDestroy($image) ;
  146.             exit ;
  147.         }
  148.     }
  149.  
  150.     // send 500 code
  151.     header("HTTP/1.0 500 Internal Server Error") ;
  152.     print($message) ;
  153.     exit ;
  154. }
  155.  
  156.  
  157. /*
  158.     decode an HTML hex-code into an array of R,G, and B values.
  159.     accepts these formats: (case insensitive) #ffffff, ffffff, #fff, fff
  160. */    
  161. function hex_to_rgb($hex)
  162. {
  163.     // remove '#'
  164.     if(substr($hex,0,1) == '#')
  165.         $hex = substr($hex,1) ;
  166.  
  167.     // expand short form ('fff') color
  168.     if(strlen($hex) == 3)
  169.     {
  170.         $hex = substr($hex,0,1) . substr($hex,0,1) .
  171.                substr($hex,1,1) . substr($hex,1,1) .
  172.                substr($hex,2,1) . substr($hex,2,1) ;
  173.     }
  174.  
  175.     if(strlen($hex) != 6)
  176.         fatal_error('Error: Invalid color "'.$hex.'"') ;
  177.  
  178.     // convert
  179.     $rgb['red'] = hexdec(substr($hex,0,2)) ;
  180.     $rgb['green'] = hexdec(substr($hex,2,2)) ;
  181.     $rgb['blue'] = hexdec(substr($hex,4,2)) ;
  182.  
  183.     return $rgb ;
  184. }
  185.  
  186.  
  187. /*
  188.     convert embedded, javascript unicode characters into embedded HTML
  189.     entities. (e.g. '%u2018' => '&#8216;'). returns the converted string.
  190. */
  191. function javascript_to_html($text)
  192. {
  193.     $matches = null ;
  194.     preg_match_all('/%u([0-9A-F]{4})/i',$text,$matches) ;
  195.     if(!empty($matches)) for($i=0;$i<sizeof($matches[0]);$i++)
  196.         $text = str_replace($matches[0][$i],
  197.                             '&#'.hexdec($matches[1][$i]).';',$text) ;
  198.  
  199.     return $text ;
  200. }
  201.  
  202. ?>
There are 5 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki