FF, no transp -> 00, medium -> 7F. */ $RecipeInfo['GoalMeter']['Version'] = '2009-01-29'; // img files are cached in cache direcory SDV($PubCacheDir, "pub/cache"); SDV($PubCacheUrl, "$PubDirUrl/cache"); SDV($GoalMeterCacheDir, $PubCacheDir); SDV($GoalMeterCacheUrl, $PubCacheUrl); mkdirp($GoalMeterCacheDir); # add markup (:goalmeter ....:) Markup('goalmeter', 'directives', '/\\(:goalmeter\\s*(.*?):\\)/ei', "GoalMeter(\$pagename, PSS('$1'))"); function GoalMeter($pagename, $opt) { global $GoalMeterCacheDir, $GoalMeterCacheUrl; // set defaults $defaults = array( 'current' => '0', # current value 'goal' => '100', # goal value 'max' => '', # max value as alternative to goal, goal will not be displayed 'height' => '360', # outer height 'width' => '', # outer width, default automatic calculation 'bar' => '3', # bar thickness 'font' => '4', #font size 1 ... 5 'bg' => 'ffffff7f',# background color (transparent) 'fill' => 'FF0000', # main fill and border color 'topfill' => 'FFFFCC', # top fill color 'bulbfill'=> '', # bulb fill color (defaults to main fill color) 'scale' => '666666', # scale color 'value' => '000000', # value text color 'percent' => 'FFFFFF', # percent text color 'border' => '', # outer border color 'nobulb' => '', # set to 1 for column only display 'noscale' => '', # set to 1 for no scale display 'padding' => '8', # img padding 'rpad' => '40', # right hand extra padding 'base' => '', # basepage to check for value updates ); $opt = array_merge($defaults, ParseArgs($opt)); // define variables static $id=0; $id++; $height = $opt['height']; $current = $opt['current']; $goal = $opt['goal']; $font = $opt['font']; $c = $opt['bar']/10; $p = $opt['padding']; $y = $height-2*$p; $rpad = (ImageFontWidth($font))*(strlen($goal))-$p; //calculate right padding $width = $opt['width']; if(!$opt['width']) $width = 80 + $rpad; // auto width $x = $width-2*$p-$rpad; // thermometer width // extract digits for $max and $cur if($opt['max']) { $max = $opt['max']; $goal = ''; } else $max = preg_replace('/\\D+/', '',$goal); $cur = preg_replace('/\\D+/', '',$current); // file handling $imgname = "thermo_".$pagename."_".$id.".png"; $imgfile = FmtPageName("$GoalMeterCacheDir/$imgname", $pagename); $imgurl = FmtPageName("$GoalMeterCacheUrl/$imgname", $pagename); $fmodtime = @filemtime($imgfile); // set mod time to last page change or last change of base page $base = $opt['base'] ? MakePageName($pagename, $opt['base']) : $pagename; $page = ReadPage($base); $modified = $page["time"]; // create new file only if older than last page mod, or does not exist if ($fmodtime < $modified || $fmodtime==0 || $modified==0) { // create outer image $img0 = ImageCreate($width, $height); // create img for thermometer $img = ImageCreate($x, $y); // convert & set colors $bg = fromhex($opt['bg'],$img); $fill = fromhex($opt['fill'],$img); if($opt['bulb']) $bulbfill = fromhex($opt['bulb'],$img); else $bulbfill = $fill; $topfill = fromhex($opt['topfill'],$img); $scale = fromhex($opt['scale'],$img); $percent = fromhex($opt['percent'],$img); // First build background to assign background color ImageFilledRectangle($img0,0,0,$width,$height,$bg); // set bottom y space if($opt['nobulb']) $by = ImageFontHeight($font)+3; else $by = $x; // Draw Top Border ImageRectangle( $img, ($x/2)-(($x/2)*$c), 0, ($x/2)+(($x/2)*$c), $y-$by+1, $fill); // Fill Top Rectangle ImageFilledRectangle( $img, ($x/2)-(($x/2)*$c)+1, 1, ($x/2)+(($x/2)*$c)-1, $y-$by+1, $topfill); // Fill to Current % ImageFilledRectangle( $img, ($x/2)-(($x/2)*$c)+1, ($y-$by)*(1-($cur/$max))+1, ($x/2)+(($x/2)*$c)-1, $y-$by+1, $fill); // Fill bulb if(!$opt['nobulb']) { ImageFilledArc($img, $x/2, $y-$x/2, $x-1, $x-1, 0, 360, $bulbfill, IMG_ARC_PIE); // Fill bulb segment top $r = $x/2; $h = ceil($r-sqrt(($r*$r)-($x*$x*$c*$c/4))); ImageFilledRectangle($img, ($x/2)-(($x/2)*$c), //x1 $y-$x, ($x/2)+(($x/2)*$c), //x2 $y-$x+$h, $fill ); } // Fill scale lines: 20 lines if(!$opt['noscale']) { for( $k=0; $k<=100; $k+=5 ) { $scx = $x/15; $scy = $scx/3; ImageFilledRectangle( $img, ($x/2)+(($x/2)*$c) -1 -$scx, ($y-$by)-($y-$by)*($k/100), ($x/2)+(($x/2)*$c) -1, ($y-$by)-($y-$by)*($k/100) +$scy, $scale ); /* // add percent numbers to scale ImageString($img, $font, ($x/2)+(($x/2)*$c) +2, (($y-$by)-($y-$by)*($k/100)) - (ImageFontHeight($font)/2) +$p, sprintf( "%2d", $k),$scale);*/ } } // Add Text Current value in percent inside bulb $pct = sprintf( "%d%%", ($cur/$max)*100 ); ImageString( $img, $font+2, ($x/2)-((strlen($pct)/2)*ImageFontWidth($font+2)), ($y-($by/2))+2 -(ImageFontHeight($font+2) / 2), $pct, $percent); // copy img to apply padding and header space ImageCopy ( $img0, $img, $p, $p+$hdr, 0, 0, $x, $y ); // Now work on outer image // Add some colors $value = fromhex($opt['value'],$img0); $border = fromhex($opt['border'],$img0); // Add outer border if set if($opt['border']) ImageRectangle($img0,0,0,$width-1,$height-1,$border); // Add Text Current value ImageString($img0, $font, ($x/2)+(($x/2)*$c)+10+$p, (($y-$by)*(1-($cur/$max)))-(ImageFontHeight($font)/2) +$p, $current, $value); // Add Text Goal value ImageString($img0, $font, ($x/2)+(($x/2)*$c)+10+$p, $p - (ImageFontHeight($font)/2)+5, $goal, $value); // Create a new image file ImagePng($img0, $imgfile); // clean memory ImageDestroy($img); ImageDestroy($img0); } // deliver img tags $out = "Current: $current"; return Keep($out); } # helperfunction to convert hexstrings to color allocations function fromhex($val,&$img) { $val = trim($val,'#'); if(strlen($val)<7) { sscanf($val, "%2x%2x%2x", $red, $green, $blue); return ImageColorAllocate($img,$red,$green,$blue); } // add alpha opacity if provided else { sscanf($val, "%2x%2x%2x%2x", $red, $green, $blue, $alpha); return ImageColorAllocateAlpha($img,$red,$green,$blue,$alpha/2); } }