01-07-2008, 02:15 PM
|
#10 (permalink)
|
|
Moderateur
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
|
Here's my code submission, it's rather long (217 lines) but could've been much, much longer!
It's a messy mixture of a collection of design patterns (badly implemented, this isn't a clean code contest) making a mess of an OOP approach. You get brownie points if you can recognise the patterns being used, hehe. The end result is a rendering of "Hello World" on the screen, as displayed in the screenshot below proving that, even with uggglllyyy code, beautiful results can be achieved... if you like red text.
Click for 100% scale version
The Code
To run this, you'll need 'Georgia.ttf' else a whole slew of errors will be thrown in your face.
PHP Code:
<?phpinterface Outputtable { public function generate (); public function output (); }abstract class HelloWorld { protected $phrase = 'Hello World'; }class HelloXml extends HelloWorld implements Outputtable { private $root = 'phrase'; public function generate () { $output = '<?xml version="1.0" encoding="utf-8"?>'; $output .= "\n"; $output .= sprintf('<%1$s>%2$s</%1$s>', $this-> root, $this-> phrase); return $output; } public function output () { header('Content-Type: application/xml; charset=utf-8'); echo $this-> generate(); }}class TextImage implements Outputtable { public $img; public $text; protected $palette; const FONT_FILE = 'Georgia.ttf'; const FONT_SIZE = 20; const FONT_ANGLE = 4; public function __construct($text) { $this-> text = $text; $this-> generate(); } public function resource () { return $this-> img; } public function generate () { $bbox = (object ) array_combine (array('llx', 'lly', 'lrx', 'lry', 'urx', 'ury', 'ulx', 'uly'), imagettfbbox (self:: FONT_SIZE, self:: FONT_ANGLE, TextImage:: FONT_FILE, $this-> text)); $width = abs(max($bbox-> lrx, $bbox-> urx) - min($bbox-> llx, $bbox-> ulx)); $height = abs(max($bbox-> lry, $bbox-> lly) - min($bbox-> ury, $bbox-> uly)); $left = min($bbox-> llx, $bbox-> lrx); $bottom = min($bbox-> lly, $bbox-> lry); $this-> img = imagecreatetruecolor ($width, $height); $this-> generate_palette(); imagefill ($this-> img, 0, 0, $this-> palette[ 'white'] ); imagettftext ($this-> img, self:: FONT_SIZE, self:: FONT_ANGLE, max(0, abs($bbox-> ulx)), self:: FONT_ANGLE < 0 ? abs($bbox-> lly - $bbox-> uly) : abs($bbox-> lly - $bbox-> ury), $this-> palette[ 'red'], self:: FONT_FILE, $this-> text); } public function output () { header('Content-Type: image/png'); imagepng ($this-> img); imagedestroy ($this-> img); } private function generate_palette () { $this-> palette = array( 'white' => imagecolorallocate ($this-> img, 255, 255, 255), 'black' => imagecolorallocate ($this-> img, 0, 0, 0 ), 'red' => imagecolorallocate ($this-> img, 255, 0, 0 ) ); }}class Image2Text implements Outputtable { private $img; private $text = 'hello'; public function __construct(TextImage $img, $text = 'text', $elem = 'span') { $this-> img = $img; $this-> elem = $elem; $this-> text = $text; } public function generate () { $img = $this-> img-> img; $width = imagesx ($img); $height = imagesy ($img); $counter = 0; $output = ''; for ($y = 0; $y < $height; $y++ ) { for ($x = 0; $x < $width; $x++ ) { $counter %= strlen($this-> text); $colour = imagecolorat ($img, $x, $y); $rgb = imagecolorsforindex ($img, $colour); $hex = self:: rgb2hex(array($rgb[ 'red'], $rgb[ 'green'], $rgb[ 'blue'] )); $output .= sprintf('<%s style="color: #%s;">%s</%s>', $this-> elem, $hex, $this-> text[ $counter], $this-> elem); $counter++; } $output .= '<br />'; } return $output; } public function output () { header('Content-Type: text/html; charset=utf-8'); echo $this-> generate(); } public static function rgb2hex ($rgb) { $rgb = array_slice(array_pad($rgb, 3, 0), 0, 3); $hex = array(); foreach ($rgb as $dec) { $hex[] = str_pad(dechex($dec), 2, '0', STR_PAD_RIGHT ); } return implode($hex); }}class HelloImage implements Outputtable { protected $source; public function __construct(HelloXml $source) { $this-> source = $source; } public function generate () { $xml_raw = $this-> source-> generate(); $xml = new SimpleXMLElement ($xml_raw); $phrase = (string ) $xml; $img = new TextImage ($phrase); $text = new Image2Text ($img, preg_replace('/[^a-zA-Z]+/', '', $phrase), 'span'); echo '<style type="text/css">body {font:normal 8px/1.0 courier, monospace;}</style>'; echo $text-> generate(); exit; return $phrase; } public function output () { //header('Content-Type: image/png'); echo $this-> generate(); }}class HelloContest extends HelloWorld implements Outputtable { protected $renderer; public function __construct() { $this-> renderer = new HelloImage (new HelloXml ); } public function generate () { } public function output () { $this-> renderer-> output(); }}// Singleton patternclass Hello { private static $instance = false; private function __construct() { } private function __clone() { } // Factory pattern public static function instance ($key) { if (self:: $instance === false and $key == 'contest') { return new HelloContest; } return self:: $instance; }}$hello = Hello:: instance('contest'); $hello-> output();
Now, to get the dirty, dirty code off I'm going to scrub myself raw with lashings of soapy water. Unclean! Unclean! 
|
|
|
|