function zem_ir_set($atts) { global $zem_ir_set; $group = (empty($atts['group']) ? 'default' : $atts['group']); $orig = (isset($zem_ir_set[$group]) ? $zem_ir_set[$group] : array()); $zem_ir_set[$group] = array_merge($orig, $atts); return ''; } function zem_ir_get_atts($atts) { global $pfr, $txpcfg, $img_dir; $group = (empty($atts['group']) ? 'default' : $atts['group']); $wraptag = (empty($atts["wraptag"]) ? "h1" : $atts["wraptag"]); $position = (empty($atts["position"]) ? "top left" : $atts["position"]); $limit = (empty($atts["limit"]) ? 0 : $atts["limit"]); $class = (empty($atts["class"]) ? "" : $atts["class"]); $font = (empty($atts["font"]) ? "" : $atts["font"]); $font_dir = (empty($atts["fontdir"]) ? dirname($txpcfg["doc_root"]) : $atts["fontdir"]); $font_size = (empty($atts["fontsize"]) ? 24 : (int)$atts["fontsize"]); $angle = (empty($atts["angle"]) ? 0 : $atts["angle"]); $color = (empty($atts["color"]) ? "#000000" : $atts["color"]); $backgroundcolor = (empty($atts["backgroundcolor"]) ? "#ffffff" : $atts["backgroundcolor"]); $cachedir = (empty($atts["cachedir"]) ? "$img_dir/zir" : $atts["cachedir"]); $ft = (isset($atts["ft"]) ? $atts["ft"] : 0); $aa = (isset($atts["aa"]) ? $atts["aa"] : 1); $info = (isset($atts["info"]) ? $atts["info"] : 0); $trans = (isset($atts["trans"]) ? $atts["trans"] : 1); $cache = (isset($atts["cache"]) ? $atts["cache"] : 1); $depth = (empty($atts["depth"]) ? 8 : $atts["depth"]); $method = (empty($atts["method"]) ? "phark" : $atts["method"]); $align = (empty($atts["align"]) ? "left" : $atts["align"]); $padding = (empty($atts["padding"]) ? "0" : $atts["padding"]); $text = (empty($atts['text']) ? '' : $atts['text']); $wrap = (empty($atts['wrap']) ? 0 : $atts['wrap']); $tr = (empty($atts['tr']) ? '' : $atts['tr']); $tt = (empty($atts['tt']) ? ' ' : $atts['tt']); $charset = (empty($atts['charset']) ? 'ISO-8859-15' : $atts['charset']); $transform = (empty($atts['transform']) ? '' : $atts['transform']); $pad = preg_split('/\s+/', trim($padding)); if (count($pad) != 4) $pad = array_fill(0, 4, $pad[0]); if (substr($font_dir, -1, 1) != DIRECTORY_SEPARATOR) $font_dir .= DIRECTORY_SEPARATOR; $font_file = $font_dir . $font; $cache_folder = $txpcfg["doc_root"].$pfr.$cachedir; return compact('wraptag', 'position', 'limit', 'class', 'font', 'font_dir', 'font_size', 'angle', 'color', 'backgroundcolor', 'cachedir', 'ft', 'aa', 'info', 'trans', 'cache', 'depth', 'method', 'align', 'padding', 'text', 'wrap', 'tr', 'charset', 'transform', 'pad', 'font_file', 'cache_folder'); } function zem_image_replace($atts, $thing) { return zem_ir($atts, $thing); } function zem_ir($atts, $thing=NULL) { global $pfr, $zem_ir_set, $txpcfg; # Merge any settings configured by zem_ir_set with the attributes for this tag $group = (empty($atts['group']) ? 'default' : $atts['group']); $defaults = (isset($zem_ir_set[$group]) ? $zem_ir_set[$group] : array()); $settings = zem_ir_get_atts(array_merge($defaults, $atts)); extract($settings); $content = $text; if ($thing) { $content = parse($thing); $text = trim(html_entity_decode(strip_tags($content), ENT_NOQUOTES, $charset)); if ($limit) $text = substr($text, 0, $limit); } if ($tr) { $tr = html_entity_decode($tr, ENT_NOQUOTES, $charset); $tt = substr(html_entity_decode($tt, ENT_NOQUOTES, $charset), 0, 1); $text = strtr($text, $tr, str_repeat($tt, strlen($tr))); } if ($transform == 'capitalize') $text = ucwords($text); elseif ($transform == 'lowercase') $text = strtolower($text); elseif ($transform == 'uppercase') $text = strtoupper($text); if ($info) { ob_start(); echo "
";
			var_dump(compact("text", "font_file", "font_size", "angle", "color", "backgroundcolor", "cache_folder", "aa", "trans", "depth", "ft", "cache", "method", "align", "pad"));
			echo "doc_root setting ".$txpcfg['doc_root']." ". ($txpcfg['doc_root'] == $_SERVER['DOCUMENT_ROOT'] ? "does" : "does not"). " match the server setting '".$_SERVER['DOCUMENT_ROOT']."'\n";
			echo "cache folder $cache_folder " . (is_dir($cache_folder) ? "is" : "is not") . " a directory\n";
			echo "cache folder $cache_folder " . (is_writable($cache_folder) ? "is" : "is not") . " writable\n";
			echo "font file $font_file " . (is_file($font_file) ? "is" : "is not") . " a file\n";
			echo "font file $font_file " . (is_readable($font_file) ? "is" : "is not") . " readable\n";
			echo "freetype 2 " . (is_callable("imagefttext") ? "is" : "is not") . " supported\n";
			echo "freetype 1 " . (is_callable("imagettfbbox") ? "is" : "is not") . " supported\n";
			echo "
"; return ob_get_clean(); } // Skip the image routines if there's no text to display if (!trim($text)) return tag($wraptag, $content); $old_umask = umask(0000); $result = dynamic_image($text, $settings); umask($old_umask); if ($result[0]) { return $result[1]; } list($error, $data, $w, $h) = $result; $url = $pfr . $cachedir . "/" . $data; $height = (empty($atts["height"]) ? $h : $atts["height"]); $width = (empty($atts["width"]) ? $w : $atts["width"]); $title = " title=\"{$text}\""; if ($class) { $style = " style=\"background: url($url) no-repeat {$position};\""; $class = " class=\"$class\""; } elseif ($method == "radu") { $style = " style=\"margin: 0 0 0 -5000px; background: url($url) no-repeat top right; height: {$height}px;\""; } elseif ($method == "lir") { $style = " style=\"padding: {$height}px 0 0 0; overflow: hidden; background: url($url) no-repeat {$position}; height: 0px !important; height /**/: {$height}px;\""; } elseif ($method == "dwyer") { $style = " style=\"background: url($url) no-repeat {$position}; height: {$height}px; width: {$width}px;\""; $spanstyle = " style=\"display: block; width: 0; height: 0; overflow: hidden;\""; $content = tag($content, "span", $spanstyle); } elseif ($method == "img") { $wraptag = "img"; $style = " src=\"{$url}\" alt=\"{$text}\""; } else { // Default: Phark Revisited $style = " style=\"text-indent: -5000px; background: url($url) no-repeat {$position}; height: {$height}px;\""; } return tag($content, $wraptag, $class.$style.$title); } # The following code is taken from Stewart Rosenberger's header.php, with modifications to allow text rotation and FT support # http://www.stewartspeak.com/headings/ function dynamic_image($content, $settings) { extract($settings); $text = $content; $transparent_background = $trans ; $mime_type = "image/png" ; $extension = ".png" ; $send_buffer_size = 4096 ; // check for GD support if(!function_exists("ImageCreate")) return array(1, "Error: Server does not support PHP image generation"); // look for cached copy, send if it exists $hash = md5(join('-', array(basename($font_file), $font_size , $color , $angle , $aa, $ft , $depth , $backgroundcolor , $trans, $padding , $wrap, $text))); $cache_filename = $cache_folder . DIRECTORY_SEPARATOR . $hash . $extension ; if($cache && is_readable($cache_filename)) { list($w, $h) = getimagesize($cache_filename); return array(0, $hash.$extension, $w, $h); } // check font availability $font_found = is_readable($font_file) ; if(!$font_found) { return array(1, "Error: The server is missing the specified font '$font_file'.") ; } // create cache dir if necessary if (!is_dir($cache_folder)) { mkdir($cache_folder, 0777); if (!is_dir($cache_folder)) { return array(1, "Error: unable to create cache folder '$cache_folder'.") ; } } if (!is_writable($cache_folder)) { return array(1, "Error: unable to write to cache folder '$cache_folder'.") ; } // create image $background_rgb = hex_to_rgb($backgroundcolor) ; $font_rgb = hex_to_rgb($color) ; if ($ft and is_callable('imageftbbox')) $boxfn = 'imageftbbox'; else $boxfn = 'imagettfbbox'; if ($wrap) { # Word wrapping is measured in characters, not pixels. We have to guess the number of characters # that will fit in the specified pixel width, then gradually reduce our guess until the text fits. $wrapstart = max($wrap/4, 80); for ($i = $wrapstart; $i >= 6; $i--) { $box = @$boxfn($font_size, 0, $font_file, wordwrap($text, $i, "\n", 1)); $wrap_w = max($box[0], $box[2], $box[4], $box[6]) - min($box[0], $box[2], $box[4], $box[6]); if ($wrap_w <= $wrap) { $text = wordwrap($text, $i, "\n", 1); break; } } } else { $box = @$boxfn($font_size,0,$font_file,$text) ; } @list($w, $h, $base_x, $base_y) = imagerotatedbbox($box, $angle, $pad); if (isset($w, $h, $base_x, $base_y)) { if ($depth == 24 and is_callable("imagecreatetruecolor")) $image = @ImageCreateTrueColor($w, $h); else $image = @ImageCreate($w,$h) ; } if(!$image || !$box) { return array(1, "Error: The server could not create this heading image.") ; } // allocate colors and draw text $background_color = ImageColorAllocate($image,$background_rgb["red"], $background_rgb["green"],$background_rgb["blue"]) ; $font_color = ImageColorAllocate($image,$font_rgb["red"], $font_rgb["green"],$font_rgb["blue"]) ; // have to explicitly draw the background color for 24-bit imageFilledRectangle($image, 0, 0, $w, $h, $background_color); if ($ft and is_callable("imagefttext")) { if (!$aa) $font_color = -$font_color; imagefttext($image, $font_size, $angle, $base_x, $base_y, $font_color, $font_file, $text) ; } else { ImageTTFText($image, $font_size, $angle, $base_x, $base_y, $font_color, $font_file, $text) ; } // set transparency if($transparent_background) ImageColorTransparent($image,$background_color) ; // save copy of image for cache ImagePNG($image,$cache_filename) ; ImageDestroy($image) ; return array(0, $hash.$extension, $w, $h); } /* decode an HTML hex-code into an array of R,G, and B values. accepts these formats: (case insensitive) #ffffff, ffffff, #fff, fff */ function hex_to_rgb($hex) { // remove "#" if(substr($hex,0,1) == "#") $hex = substr($hex,1) ; // expand short form ("fff") color if(strlen($hex) == 3) { $hex = substr($hex,0,1) . substr($hex,0,1) . substr($hex,1,1) . substr($hex,1,1) . substr($hex,2,1) . substr($hex,2,1) ; } if(strlen($hex) != 6) print("Error: Invalid color \"$hex\"") ; // convert $rgb["red"] = hexdec(substr($hex,0,2)) ; $rgb["green"] = hexdec(substr($hex,2,2)) ; $rgb["blue"] = hexdec(substr($hex,4,2)) ; return $rgb ; } // Determine the text bounding box after rotation is applied function imagerotatedbbox($bbox, $angle=0, $pad=0) { if (count($bbox) != 8) return; if (empty($pad)) $pad = array(0,0,0,0); $a = $angle * M_PI / 180; $cosa = cos($a); $sina = sin($a); $result = array(); # baseline and total width/height of text when horizontal $base_x = abs($bbox[6]); $base_y = abs($bbox[7]); $old_w = max($bbox[0], $bbox[2], $bbox[4], $bbox[6]) - min($bbox[0], $bbox[2], $bbox[4], $bbox[6]); $old_h = max($bbox[1], $bbox[3], $bbox[5], $bbox[7]) - min($bbox[1], $bbox[3], $bbox[5], $bbox[7]); // rotate the box coordinates to get the new width & height of the final image for ($i = 0; $i < 7; $i += 2) { $result[$i] = round($bbox[$i] * $cosa + $bbox[$i+1] * $sina); $result[$i+1] = round($bbox[$i+1] * $cosa - $bbox[$i] * $sina); } $w = max($result[0], $result[2], $result[4], $result[6]) - min($result[0], $result[2], $result[4], $result[6]); $h = max($result[1], $result[3], $result[5], $result[7]) - min($result[1], $result[3], $result[5], $result[7]); $pad_w = $w + ($pad[3] + $pad[1]); $pad_h = $h + ($pad[0] + $pad[2]); // center of bounding box (xc,yc); $xc = $old_w/2.0; $yc = $old_h/2.0; // center of image $px = $w/2.0; $py = $h/2.0; // baseline coordinates relative to the center $x1 = $base_x - $xc; $y1 = $base_y - $yc; // baseline after rotation $x2= intval( $x1*$cosa+$y1*$sina+$px+0.5); $y2= intval(-$x1*$sina+$y1*$cosa+$py+0.5); return array($pad_w, $pad_h, $x2 + $pad[3], $y2 + $pad[0]); }