Created
June 26, 2021 20:12
-
-
Save jaydreyer/58eb413beeada300e70cc6660539f2bf to your computer and use it in GitHub Desktop.
zem_ir image replacement textpattern plugin code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "<pre>"; | |
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" : "<b>does not</b>"). " match the server setting '".$_SERVER['DOCUMENT_ROOT']."'\n"; | |
echo "cache folder $cache_folder " . (is_dir($cache_folder) ? "is" : "is <b>not</b>") . " a directory\n"; | |
echo "cache folder $cache_folder " . (is_writable($cache_folder) ? "is" : "is <b>not</b>") . " writable\n"; | |
echo "font file $font_file " . (is_file($font_file) ? "is" : "is <b>not</b>") . " a file\n"; | |
echo "font file $font_file " . (is_readable($font_file) ? "is" : "is <b>not</b>") . " readable\n"; | |
echo "freetype 2 " . (is_callable("imagefttext") ? "is" : "is <b>not</b>") . " supported\n"; | |
echo "freetype 1 " . (is_callable("imagettfbbox") ? "is" : "is <b>not</b>") . " supported\n"; | |
echo "</pre>"; | |
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]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment