'./out.png', /** Text to render (UTF-8) */ 'text' => false, /** Font file */ 'font' => false, /** Color (R, G, B): int, 0-255 */ 'color' => array(0,0,0), /** Background color (R, G, B, Alpha) * R/G/B: int = 0-255 * Alpha: int = 0-127 (0: opaque, 127: transparent) */ 'bg' => array(255,255,255,127), /** Size in points */ 'size' => 10, /** Dots per inch (DPI) */ 'res' => 96, 'angle' => 0, /**< Angle in degrees */ 'slant' => 0.0, /**< Slant in degrees */ 'wm' => 1.0, /**< Width Multiplier */ 'hm' => 1.0, /**< Height Multiplier */ 'am' => 1.0, /**< Advance Multiplier */ 'uline' => 0, /**< Bool: show underline or not */ ); /** getopt() */ var $shortOpts = "t:f:s:r:o:x:SHBaImlAh"; /** extrainfo to getfttext */ var $ft_opts = array('hdpi' => 96, 'vdpi' => 96,); /** Bounding box width */ var $boxW = 0; /** Bounding box height */ var $boxH = 0; /** Text X pos */ var $txtX = 0; /** Text Y pos */ var $txtY = 0; /** Entry point */ function main() { // Parse options $this->getOpts(); // Evaluate image dimensions & calculate bounding box $this->evalBitmap(); // Render text and save to file $this->draw(); } // main() /** Show usage information */ function usage() { $a = $_SERVER['argv']; echo "{$a[0]} \n". " Options (* means requires)\n". " -h This help\n". "\n". " -t \"txt\" *Text to generate\n". " -o name Out file (png, default: out.png)\n". " -f fnt.ttf *Font file\n". " -s size Font size (default = 10)\n". " -r dpi DPI to use\n". "\n". " -S load_no_scale\n". " -H load_no_hinting\n". " -B load_no_bitmap\n". " -a load_force_autohint\n". " -I load_load_ignore_transform\n". " -m load_monochrome\n". " -l load_linear_design\n". " -A load_no_autohint\n". " -x slant,wm,hm,am Various transformations:\n". " slant: Slant Angle, degrees (def: 0.0)\n". " wm: Width Multiplier (def: 1.0)\n". " hm: Height Multiplier (def: 1.0)\n". " am: Advance Multiplier (def: 1.0)\n". ""; } // usage() /** Parse options */ function getOpts() { $options = getopt($this->shortOpts); $missing = array('t' => 'Text to render required', 'f' => 'Font file required', ); $fto = array('S' => 'load_no_scale', 'H' => 'load_no_hinting', 'B' => 'load_no_bitmap', 'a' => 'load_force_autohint', 'I' => 'load_load_ignore_transform', 'm' => 'load_monochrome', 'l' => 'load_linear_design', 'A' => 'load_no_autohint', ); foreach ($options as $k => $v) { switch ($k) { case 'h': $this->usage(); exit(0); case 't': $this->o['text'] = $v; unset($missing['t']); break; case 'f': $this->o['font'] = $v; unset($missing['f']); break; case 'o': $this->o['out'] = $v; break; case 's': $this->o['size'] = (int)$v; break; case 'r': $this->o['res'] = (int)$v; $this->ft_opts['hdpi'] = (int)$v; $this->ft_opts['vdpi'] = (int)$v; break; case 'S': case 'H': case 'B': case 'a': case 'I': case 'm': case 'l': case 'A': $this->ft_opts[$fto[$k]] = 1; break; case 'x': $tmp = explode(',', $v); if (isset($tmp[0]) && $tmp[0] != '') { $this->o['slant'] = $tmp[0]; $this->ft_opts['slant_angle'] = $tmp[0] * M_PI / 180.0; } if (isset($tmp[1]) && $tmp[1] != '') { $this->o['wm'] = $tmp[1]; $this->ft_opts['width_mult'] = $tmp[1]; } if (isset($tmp[2]) && $tmp[2] != '') { $this->o['hm'] = $tmp[2]; $this->ft_opts['height_mult'] = $tmp[2]; } if (isset($tmp[3]) && $tmp[3] != '') { $this->o['am'] = $tmp[3]; $this->ft_opts['advance_mult'] = $tmp[3]; } break; } } if (count($missing) > 0) { foreach ($missing as $k => $v) { echo "Missing argument '$k': $v\n"; } $this->usage(); exit(-1); } } // getOpts() /** Calculate bounding boxes and stuff */ function evalBitmap() { /* Notes on bounding boxes * * TL TR * +----------------------------------------------------------+ * | | | * | | | * | | (0,0) | * | |/ | * |-----+----------------------------------------------------| * | | | * | | | * +----------------------------------------------------------+ * BL BR * * a=0 Descrition si a != 0 * 0: xMin cos(a) - yMin sin(a) xMin x du coin BL * 1: xMin sin(a) - yMin cos(a) -yMin y min (y de BL) * 2: xMax cos(a) - yMin sin(a) xMax x max (x de BR) * 3: xMax sin(a) - yMin cos(a) -yMin y de BR * 4: xMax cos(a) - yMax sin(a) xMax x de TR * 5: xMax sin(a) - yMax cos(a) -yMax y max (y de TR) * 6: xMin cos(a) - yMax sin(a) xMin x min (x de TL) * 7: xMin sin(a) - yMax cos(a) -yMax y de TL * * C'est tout fucké.. alors utilisons nos propres calculs. */ $s = Imageftbbox($this->o['size'], 0, $this->o['font'], $this->o['text'], $this->ft_opts); $width = abs($s[2] - $s[6]); $height = abs($s[1] - $s[5]); // Convert size of fonts from points to pixels $pixelSize = (float)($this->o['size'] * $this->ft_opts['vdpi']) / 72.0; // x: vers la droite // y: vers le bas // (0,0) = baseline, coin gauche $dims = array('tl' => array($s[0], $s[5]), 'tr' => array($s[2], $s[5]), 'br' => array($s[2], $s[1]), 'bl' => array($s[0], $s[1]) ); // Underline stuff.. #if ($this->o['uline']) { # $ulineThickness = (int)abs( $this->o['hm'] * $this->fnt['fntUlineThick'] * $pixelSize / (float)$this->fnt['fntEmSize']); # $ulinePosition = (int)(-1 * ( $this->o['hm'] * $this->fnt['fntUlinePos'] * $pixelSize / (float)$this->fnt['fntEmSize'] + $ulineThickness/2) + .5); # if ($ulineThickness < 1) $ulineThickness = 1; # $ulineLeft = $s[0] - 1.5*abs($ulineThickness); # $ulineRight = $s[2] + 1.5*abs($ulineThickness); # $dims['uposl'] = array($ulineLeft, $ulinePosition); # $dims['uposr'] = array($ulineRight, $ulinePosition); #} // On applique une rotation de "a" $a = $this->o['angle'] * M_PI / 180.0; $cosa = cos($a); $sina = sin($a); $dimsp = array(); $xMin = $xMax = $yMin = $yMax = false; $all_x = $all_y = array(); foreach ($dims as $tag => $c) { $dimsp[$tag] = array($c[1]*$sina + $this->o['am']*$this->o['wm']*$c[0]*$cosa, $c[1]*$cosa - $this->o['am']*$this->o['wm']*$c[0]*$sina); $all_x[] = $dimsp[$tag][0]; $all_y[] = $dimsp[$tag][1]; } $bbox = array(min($all_x), max($all_x), min($all_y), max($all_y)); #$bbox = array(min($s[0], $s[2], $s[4], $s[6]), # max($s[0], $s[2], $s[4], $s[6]), # min($s[1], $s[3], $s[5], $s[7]), # max($s[1], $s[3], $s[5], $s[7]) # ); $width = abs($bbox[1] - $bbox[0]); $height = abs($bbox[3] - $bbox[2]); $base = array(-$bbox[0], -$bbox[2]); // Padding #$width += 6; $height += 6; #$base[0] += 3; $base[1] += 3; #echo "bbox:
";print_r($bbox);exit;
        #echo "Orig: 
"; print_r($dims) ; echo "

Rot of $a rads:
";print_r($dimsp);echo "
";exit; // Padding: pour l'instant, on fixe à 3 pixels $this->boxW = 10 + $width; $this->boxH = 10 + $height; $this->txtX = 5 + $base[0]; $this->txtY = 5 + $base[1]; #if ($this->o['uline']) { # $this->ulinePos = array($dimsp['uposl'], $dimsp['uposr']); # $this->ulineThick = $ulineThickness; #} #$this->txtX = 3; #$this->txtY = 3 + $height; #echo "({$this->boxW} x {$this->boxH}) :: ({$this->txtX},{$this->txtY})
\n"; #exit; return true; } // evalBitmap() /** Render text and save file */ function draw() { $this->img = imagecreatetruecolor($this->boxW, $this->boxH); imagealphablending($this->img, false); $bgcolor = imagecolorallocatealpha($this->img, $this->o['bg'][0], $this->o['bg'][1], $this->o['bg'][2], $this->o['bg'][3]); $fgcolor = imagecolorallocatealpha($this->img, $this->o['color'][0], $this->o['color'][1], $this->o['color'][2], 0); // 100% opaque imagefilledrectangle($this->img, 0, 0, $this->boxW-1, $this->boxH-1, $bgcolor); imagealphablending($this->img, true); // Underline #if ($this->o['uline']) { # // Force 1 px de thickness :| # //imageantialias($this->img, !isset($this->ft_opts['monochrome'])); # imagesetthickness($this->img, $this->ulineThick); # imageline($this->img, # $this->ulinePos[0][0] + $this->txtX, $this->ulinePos[0][1] + $this->txtY, # $this->ulinePos[1][0] + $this->txtX, $this->ulinePos[1][1] + $this->txtY, # $fgcolor); #} #echo "
";print_r($this->ulinePos);echo "\n\n
thick: {$this->ulineThick}
\n";exit; ImageFtText($this->img, $this->o['size'], $this->o['angle'], $this->txtX, $this->txtY, $fgcolor, $this->o['font'], $this->o['text'], $this->ft_opts); #$xcolor = imagecolorallocate($this->img, 255, 0, 0); #imagesetpixel($this->img, $this->txtX, $this->txtY, $xcolor); imagesavealpha($this->img, true); imagepng($this->img, $this->o['out']); return true; } // draw() } // Generate $g = new Generate(); $g->main();