aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/captcha/captcha_gd.php
diff options
context:
space:
mode:
authorDavid M <davidmj@users.sourceforge.net>2006-11-03 23:09:16 +0000
committerDavid M <davidmj@users.sourceforge.net>2006-11-03 23:09:16 +0000
commit8b0ec6e02d5a53ea3d1b87abd122d39cc3e8366f (patch)
tree22bae5ecbab9dbf8390ab3763f53c15c822c9198 /phpBB/includes/captcha/captcha_gd.php
parent7ab232a45504ef357a19d9ab58dd27c454e12784 (diff)
downloadforums-8b0ec6e02d5a53ea3d1b87abd122d39cc3e8366f.tar
forums-8b0ec6e02d5a53ea3d1b87abd122d39cc3e8366f.tar.gz
forums-8b0ec6e02d5a53ea3d1b87abd122d39cc3e8366f.tar.bz2
forums-8b0ec6e02d5a53ea3d1b87abd122d39cc3e8366f.tar.xz
forums-8b0ec6e02d5a53ea3d1b87abd122d39cc3e8366f.zip
- compress is nicer (fixed a bug :P)
- UTF-8 code is nicer (fixed a bug :P) - new CAPTCHA. Replaced the old one for size and usability issues. The old CAPTCHA will most likely be released as a separate package git-svn-id: file:///svn/phpbb/trunk@6549 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes/captcha/captcha_gd.php')
-rw-r--r--phpBB/includes/captcha/captcha_gd.php3434
1 files changed, 81 insertions, 3353 deletions
diff --git a/phpBB/includes/captcha/captcha_gd.php b/phpBB/includes/captcha/captcha_gd.php
index 34b1684f3c..e249a46c04 100644
--- a/phpBB/includes/captcha/captcha_gd.php
+++ b/phpBB/includes/captcha/captcha_gd.php
@@ -9,3429 +9,157 @@
*/
/**
-* This file is getting too large.
-*
-* Only bugfixes allowed from now on.
-* If a policy can not be fixed with the minimum amount of code it gets removed.
-*/
-
-/**
-* Main gd based captcha class
-*
-* Thanks to Robert Hetzler (Xore)
+* Based on PHP-Class hn_captcha Version 1.3, released 11-Apr-2006
+* Original Author - Horst Nogajski, horst@nogajski.de
*
* @package VC
*/
class captcha
{
- /**
- * Create the image containing $code
- */
- function execute($code, $policy)
- {
- $this->$policy(str_split($code));
- }
-
- /**
- * Send image and destroy
- */
- function send_image(&$image)
- {
- header('Content-Type: image/png');
- header('Cache-control: no-cache, no-store');
- imagepng($image);
- imagedestroy($image);
- }
-
- /**
- *
- */
- function wave_height($x, $y, $factor = 1, $tweak = 1)
- {
- return ((sin($x / (3 * $factor)) + sin($y / (3 * $factor))) * 10 * $tweak);
- }
-
- /**
- *
- */
- function grid_height($x, $y, $factor = 1, $x_grid, $y_grid)
- {
- return ( (!($x % ($x_grid * $factor)) || !($y % ($y_grid * $factor))) ? 3 : 0);
- }
-
- /**
- *
- */
- function draw_shape($type, $img, $x_min, $y_min, $x_max, $y_max, $color)
- {
- switch ($type)
- {
- case 'Square':
- imagefilledpolygon($img, array($x_min, $y_max, $x_min, $y_min, $x_max, $y_min, $x_max, $y_max), 4, $color);
- break;
-
- case 'TriangleUp':
- imagefilledpolygon($img, array($x_min, $y_max, ($x_min + $x_max) / 2, $y_min, $x_max, $y_max), 3, $color);
- break;
-
- case 'TriangleDown':
- imagefilledpolygon($img, array($x_min, $y_min, ($x_min + $x_max) / 2, $y_max, $x_max, $y_min), 3, $color);
- break;
-
- case 'Circle':
- imagefilledellipse($img, ($x_min + $x_max) / 2, ($y_min + $y_max) / 2, $x_max - $x_min, $y_max - $y_min, $color);
- break;
- }
- }
-
- /**
- *
- */
- function draw_pattern($seed, $img, $x_min, $y_min, $x_max, $y_max, $colors, $thickness = 1)
- {
- $x_size = ($x_max - $x_min) / 4;
- $y_size = ($y_max - $y_min) / 4;
- $bitmap = substr($seed, 16, 4);
- $numcolors = sizeof($colors) - 1;
- for ($y = 0; $y < 4; ++$y)
- {
- $map = hexdec(substr($bitmap, $y, 1));
- for ($x = 0; $x < 4; ++$x)
- {
- if ($map & (1 << $x))
- {
- $char = hexdec(substr($seed, ($y << 2) + $x, 1));
- if (!($char >> 2))
- {
- switch ($char & 3)
- {
- case 0:
- $shape = 'Circle';
- break;
-
- case 1:
- $shape = 'Square';
- break;
-
- case 2:
- $shape = 'TriangleUp';
- break;
-
- case 3:
- $shape = 'TriangleDown';
- break;
- }
- $this->draw_shape($shape, $img, $x_min + ($x * $x_size), $y_min + ($y * $y_size), $x_min + (($x + 1) * $x_size), $y_min + (($y + 1) * $y_size), $colors[array_rand($colors)]);
- }
- }
- }
- }
-
- $cells = array();
- for ($i = 0; $i < 6; ++$i)
- {
- $cells = hexdec(substr($seed, 20 + ($i << 1), 2));
- $x1 = $cells & 3;
- $cells = $cells >> 2;
- $y1 = $cells & 3;
- $cells = $cells >> 2;
- $x2 = $cells & 3;
- $cells = $cells >> 2;
- $y2 = $cells & 3;
- $x1_real = $x_min + (($x1 + 0.5) * $x_size);
- $y1_real = $y_min + (($y1 + 0.5) * $y_size);
- $x2_real = $x_min + (($x2 + 0.5) * $x_size);
- $y2_real = $y_min + (($y2 + 0.5) * $y_size);
- if ($thickness > 1)
- {
- imagesetthickness($img, $thickness);
- }
- imageline($img, $x1_real, $y1_real, $x2_real, $y2_real, $colors[array_rand($colors)]);
- if ($thickness > 1)
- {
- imagesetthickness($img, 1);
- }
- }
- }
-
- /**
- *
- */
- function get_char_string()
- {
- static $chars = false;
- static $charcount = 0;
- if (!$chars)
- {
- $chars = array_merge(range('A', 'Z'), range('1', '9'));
- }
- $word = '';
- for ($i = mt_rand(6, 8); $i > 0; --$i)
- {
- $word .= $chars[array_rand($chars)];
- }
- return $word;
- }
-
- /**
- * shape
- */
- function policy_shape($code)
- {
- global $config, $user;
- // Generate image
- $img_x = 800;
- $img_y = 250;
- $img = imagecreatetruecolor($img_x, $img_y);
-
- // Generate colors
- $c = new color_manager($img, array(
- 'random' => true,
- 'min_saturation' => 70,
- 'min_value' => 65,
- ));
-
- $primaries = $c->color_scheme('background', 'tetradic', false);
-
- $noise = array_shift($primaries);
- $noise = $c->mono_range($noise, 'value', 5, false);
- $primaries = $c->mono_range($primaries, 'value', 5, false);
-
- // Generate code characters
- $characters = array();
- $sizes = array();
- $bounding_boxes = array();
- $width_avail = $img_x;
- $code_num = sizeof($code);
- $char_class = $this->captcha_char('char_ttf');
- for ( $i = 0; $i < $code_num; ++$i )
- {
- $characters[$i] = new $char_class($code[$i]);
- list($min, $max) = $characters[$i]->range();
- $sizes[$i] = mt_rand($min, $max / 2);
- $box = $characters[$i]->dimensions($sizes[$i]);
- $width_avail -= ($box[2] - $box[0]);
- $bounding_boxes[$i] = $box;
- }
-
- // Redistribute leftover x-space
- $offset = array();
- for ( $i = 0; $i < $code_num; ++$i )
- {
- $denom = ($code_num - $i);
- $denom = max(1.5, $denom);
- $offset[$i] = mt_rand(0, (1.5 * $width_avail) / $denom);
- $width_avail -= $offset[$i];
- }
-
- // Add some line noise
- if ($config['policy_shape_noise_line'])
- {
- $this->noise_line($img, 0, 0, $img_x, $img_y, $c->r('background'), $primaries, $noise);
- }
-
- $real = mt_rand(0, 3);
- $patterns = array('', '', '', '');
- for ($i = 32; $i > 0; --$i)
- {
- $patterns[$i & 3] .= str_pad(dechex(mt_rand(0, 65535)), 4, '0', STR_PAD_LEFT);
- }
-
-
- for ($i = 0; $i < 4; ++$i)
- {
- /*if ($i)
- {
- $y = 5 + ($i * 60);
- imageline($img, 550, $y, 650, $y, $fontcolors[0]);
- }*/
- $this->draw_pattern($patterns[$i], $img, 525, 10 + ($i * 60), 575, ($i + 1) * 60, $primaries);
- if ($i == $real)
- {
- $this->draw_pattern($patterns[$i], $img, 25, 25, 225, 225, $primaries, 3);
- for ($j = 0; $j < $code_num; ++$j)
- {
- $character = new $char_class($code[$j]);
- $character->drawchar(25, 600 + ($j * 25), 35 + ($i * 60), $img, $c->r('background'), $primaries);
- }
- }
- else
- {
- $word = $this->get_char_string();
- for ($j = strlen($word) - 1; $j >= 0; --$j)
- {
- $character = new $char_class(substr($word, $j, 1));
- $character->drawchar(25, 600 + ($j * 25), 35 + ($i * 60), $img, $c->r('background'), $primaries);
- }
- }
- }
-
- $count = sizeof($user->lang['CAPTCHA']['shape']);
- $line_height = $img_y / ($count + 1);
- for ($i = 0; $i < $count; ++$i)
- {
- $text = $user->lang['CAPTCHA']['shape'][$i];
- $line_width = strlen($text) * 4.5; // ( / 2, * 9 )
- imagestring($img, 6, ($img_x / 2) - $line_width - 1, $line_height * ($i + 1) - 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width - 1, $line_height * ($i + 1) + 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width + 1, $line_height * ($i + 1) + 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width + 1, $line_height * ($i + 1) - 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width, $line_height * ($i + 1), $text, $c->r('white'));
- }
-
-
- // Add some pixel noise
- if ($config['policy_shape_noise_pixel'])
- {
- $this->noise_pixel($img, 0, 0, $img_x, $img_y, $c->r('background'), $primaries, $noise, $config['policy_shape_noise_pixel']);
- }
-
- // Send image
- $this->send_image($img);
- }
-
- function policy_composite($code)
- {
- // Generate image
- $img_x = 800;
- $img_y = 250;
- $img = imagecreate($img_x, $img_y);
-
- $map = captcha_vectors();
- $fonts = captcha_load_ttf_fonts();
-
- // Generate basic colors
- $c = new color_manager($img, 'white');
- $c->allocate_named('primary', array(
- 'random' => true,
- 'min_saturation' => 50,
- 'min_value' => 75,
- ));
- $bg_colors = $c->color_scheme('primary', 'triadic', false);
- $text_colors = $c->mono_range('primary', 'saturation', 6);
- $bg_colors = $c->mono_range($bg_colors, 'saturation', 6);
-
- // Specificy image portion dimensions.
- $count = sizeof($code);
- $cellsize = $img_x / $count;
- $y_range = min($cellsize, $img_y);
- $y_max = $img_y - $y_range;
- $y_off = array(); // consecutive vertical offset of characters
- $color = array(); // color of characters
- $y_off[0] = mt_rand(0, $y_max);
- for ($i = 1; $i < $count; ++$i)
- {
- // each consective character can be as much as 50% closer to the top or bottom of the image as the previous
- $diff = mt_rand(-50, 50);
- if ($diff > 0)
- {
- $y_off[$i] = $y_off[$i - 1] + ((($y_max - $y_off[$i - 1]) * $diff) / 100);
- }
- else
- {
- $y_off[$i] = $y_off[$i - 1] * ((100 + $diff) / 100);
- }
- }
-
- $range = 0.075;
-
- $chars = array_merge(range('A', 'Z'), range('1', '9'));
-
- // draw some characters. if they're within the vector spec of the code character, color them differently
- for ($i = 0; $i < 8000; ++$i)
- {
- $degree = mt_rand(-30, 30);
- $x = mt_rand(0, $img_x - 1);
- $y = mt_rand(0, $img_y);
- $text = $chars[array_rand($chars)];
- $char = $x / $cellsize;
- $meta_x = ((($x % $cellsize) / $cellsize) * 1.5) - 0.25;
- $meta_y = (($img_y - $y) - $y_off[$char]) / $y_range;
- $font = $fonts[array_rand($fonts)];
-
- $distance = vector_distance($map[$code[$char]], $meta_x, $meta_y, $range);
-
- $switch = !(rand() % 100);
-
- imagettftext($img, 10, $degree, $x, $y,
- (($distance <= $range) xor $switch) ?
- $c->r_rand($text_colors) :
- $c->r_rand($bg_colors),
- $font, $text);
-
- }
-
- // Send image
- $this->send_image($img);
- }
-
- function policy_stencil($code)
- {
- // Generate image
- $img_x = 800;
- $img_y = 250;
- $img = imagecreatetruecolor($img_x, $img_y);
- $stencil = imagecreatetruecolor($img_x, $img_y);
-
- $map = captcha_vectors();
- $fonts = captcha_load_ttf_fonts();
-
- // Generate colors
- $c = new color_manager($img, 'black');
- $cs = new color_manager($stencil, 'gray');
-
- $c->allocate_named('primary', array(
- 'random' => true,
- 'min_saturation' => 75,
- 'min_value' => 80,
- ));
-
- $secondary = $c->color_scheme('primary', 'triadic', false);
-
- //imagefill($stencil, 0, 0, $black2);
- //imagefill($img, 0, 0, $white1);
-
- $chars = array_merge(range('A', 'Z'), range('1', '9'));
- $step = 20;
- $density = 4;
- for ($i = 0; $i < $img_x; $i += $step)
- {
- for ($j = 0; $j < $img_y; $j += $step)
- {
- for ($k = 0; $k < $density; ++$k)
- {
- $degree = mt_rand(-30, 30);
- $x = mt_rand($i, $i + $step);
- $y = mt_rand($j, $j + $step);
- $char = $chars[array_rand($chars)];
- $font = $fonts[array_rand($fonts)];
- imagettftext($stencil, mt_rand(20, 30), $degree, $x, $y, $cs->r('black'), $font, $char);
- }
- }
- }
-
- for ($i = 0; $i < 3; ++$i)
- {
- $degree1 = mt_rand(-30, 30);
- $degree2 = mt_rand(-30, 30);
- $x1 = mt_rand(0, $img_x - 1);
- $x2 = mt_rand(0, $img_x - 1);
- $y1 = mt_rand(0, $img_y);
- $y2 = mt_rand(0, $img_y);
- $char1 = $chars[array_rand($chars)];
- $char2 = $chars[array_rand($chars)];
- $font1 = $fonts[array_rand($fonts)];
- $font2 = $fonts[array_rand($fonts)];
-
- imagettftext($img, mt_rand(75, 100), $degree1, $x1, $y1, $secondary[0], $font1, $char1);
- imagettftext($img, mt_rand(75, 100), $degree2, $x2, $y2, $secondary[1], $font2, $char2);
- }
-
- $characters = array();
- $sizes = array();
- $bounding_boxes = array();
- $width_avail = $img_x;
- $code_num = sizeof($code);
- $char_class = $this->captcha_char('char_ttf');
- for ($i = 0; $i < $code_num; ++$i)
- {
- $characters[$i] = new $char_class($code[$i]);
- $sizes[$i] = mt_rand(75, 100);
- $box = $characters[$i]->dimensions($sizes[$i]);
- $width_avail -= ($box[2] - $box[0]);
- $bounding_boxes[$i] = $box;
- }
-
- //
- // Redistribute leftover x-space
- //
- $offset = array();
- for ($i = 0; $i < $code_num; ++$i)
- {
- $denom = ($code_num - $i);
- $denom = max(1.5, $denom);
- $offset[$i] = mt_rand(0, (1.5 * $width_avail) / $denom);
- $width_avail -= $offset[$i];
- }
-
- // Draw the text
- $xoffset = 0;
- for ($i = 0; $i < $code_num; ++$i)
- {
- $characters[$i] = new $char_class($code[$i]);
- $dimm = $bounding_boxes[$i];
- $xoffset += ($offset[$i] - $dimm[0]);
- $yoffset = mt_rand(-$dimm[1], $img_y - $dimm[3]);
- $characters[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $c->r('background'), array($c->r('primary')));
- $xoffset += $dimm[2];
- }
-
- for ($i = 0; $i < $img_x; ++$i)
- {
- for ($j = 0; $j < $img_y; ++$j)
- {
- // if the stencil is not black, set the pixel in the image to gray
- if (imagecolorat($stencil, $i, $j))
- {
- imagesetpixel($img, $i, $j, $c->r('gray'));
- }
- }
- }
-
- // Send image
- $this->send_image($img);
- }
-
- function policy_cells($code)
- {
- global $user;
- // Generate image
- $img_x = 800;
- $img_y = 250;
- $img = imagecreate($img_x, $img_y);
-
- $fonts = captcha_load_ttf_fonts();
-
- $map = captcha_vectors();
-
- //
- // Generate colors
- //
- $c = new color_manager($img, 'white');
-
- $c->allocate_named('primary', array(
- 'random' => true,
- 'min_saturation' => 30,
- 'min_value' => 65,
- ));
- $primaries = $c->color_scheme('primary', 'tetradic');
- $bg_colors = $c->mono_range($primaries, 'value', 4, false);
- shuffle($primaries);
- shuffle($bg_colors);
-
- // Randomize the characters on the right and the left
- $left_characters = array();
- $right_characters = array();
- $chars = array_merge(range('A', 'Z'), range('1', '9'));
- $chars_size = sizeof($chars) - 1;
- $alpha = range('A', 'Z');
- $alpha_size = sizeof($alpha) - 1;
- for ($i = 0; $i < 25; ++$i)
- {
- $left_characters[$i] = $alpha[mt_rand(0, $alpha_size)];
- $right_characters[$i] = $chars[mt_rand(0, $chars_size)];
- }
-
- // Pick locations for our code, shuffle the rest into 3 separate queues
- $code_count = sizeof($code);
- $code_order = range(0, 24);
- shuffle($code_order);
- $remaining = array_splice($code_order, $code_count);
- $lineups = array($code_order, array(), array(), array());
- for ($i = sizeof($remaining) - 1; $i >= 0; --$i)
- {
- $lineups[mt_rand(1, 3)][] = $remaining[$i];
- }
-
- // overwrite the randomized left and right values with our code, where applicable
- for ($i = 0; $i < $code_count; ++$i)
- {
- $left_characters[$code_order[$i]] = $i + 1;
- $right_characters[$code_order[$i]] = $code[$i];
- }
-
-
- $offset1 = 50;
- $offset2 = 550;
-
- // Draw the cells and right hand characters
- $xs = $ys = array();
- for ($i = 0; $i < 25; ++$i)
- {
- $xs[$i] = $offset1 + 20 + (($i % 5) * 40) + mt_rand(-13, 13);
- $ys[$i] = 45 + (intval($i / 5) * 40) + mt_rand(-13, 13);
-
- $bg = $c->r_rand($bg_colors);
-
- // fill the cells with the background colors
- imagefilledrectangle($img,
- $offset1 + 1 + (($i % 5) * 40), 26 + (intval($i / 5) * 40),
- $offset1 + 39 + (($i % 5) * 40), 64 + (intval($i / 5) * 40),
- $bg);
- imagefilledrectangle($img,
- $offset2 + 1 + (($i % 5) * 40), 26 + (intval($i / 5) * 40),
- $offset2 + 39 + (($i % 5) * 40), 64 + (intval($i / 5) * 40),
- $bg);
-
- $level = intval($i / 5);
- $pos = $i % 5;
- imagettftext($img, 12, 0,
- $offset2 + 15 + ($pos * 40), 50 + ($level * 40),
- $c->is_dark($bg) ? $c->r('white'): $c->r('black'), $fonts['genr102.ttf'], $right_characters[$i]);
- }
-
- // draw the lines that appear between nodes (visual hint)
- for ($k = 0; $k < 4; ++$k )
- {
- $lineup = $lineups[$k];
- for ($i = 1, $size = sizeof($lineup); $i < $size; ++$i )
- {
- imageline($img,
- $xs[$lineup[$i - 1]], $ys[$lineup[$i - 1]],
- $xs[$lineup[$i]], $ys[$lineup[$i]],
- $primaries[$k]);
- }
- }
-
- // draw the actual nodes
- $textcolor = $c->is_dark($primaries[0]) ? $c->r('white') : $c->r('black');
- for ($k = 0; $k < 4; ++$k )
- {
- for ($j = 0, $size = sizeof($lineups[$k]); $j < $size; ++$j )
- {
- $i = $lineups[$k][$j];
- imagefilledellipse($img,
- $xs[$i], $ys[$i],
- 20, 20,
- $primaries[$k]);
- imagettftext($img, 12, 0,
- $xs[$i] - 5, $ys[$i] + 5,
- $textcolor, $fonts['genr102.ttf'], $left_characters[$i]);
- }
- }
-
- // Draw poly behind explain text
- $points = mt_rand(3, 6);
- $arc = 360 / $points;
- $vertices = array();
- $c_x = $img_x / 2;
- $c_y = $img_y / 2;
- $radius = $img_y / 2.5;
- $start = deg2rad(mt_rand(0, 360));
- for ($i = 0; $i < $points; ++$i)
- {
- $rad = $start + deg2rad(($arc * $i) + mt_rand(-10, 10));
- $vertices[] = $c_x + (cos($rad) * $radius);
- $vertices[] = $c_y + (sin($rad) * $radius);
- }
- imagefilledpolygon($img, $vertices, $points, $primaries[mt_rand(0,3)]);
-
- // draw explain text
- $count = sizeof($user->lang['CAPTCHA']['cells']);
- $line_height = $img_y / ($count + 1);
- for ($i = 0; $i < $count; ++$i)
- {
- $text = $user->lang['CAPTCHA']['cells'][$i];
- $line_width = strlen($text) * 4.5; // ( / 2, * 9 )
- imagestring($img, 6, ($img_x / 2) - $line_width - 1, $line_height * ($i + 1) - 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width - 1, $line_height * ($i + 1) + 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width + 1, $line_height * ($i + 1) + 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width + 1, $line_height * ($i + 1) - 1, $text, $c->r('black'));
- imagestring($img, 6, ($img_x / 2) - $line_width, $line_height * ($i + 1), $text, $c->r('white'));
- }
-
- // Send image
- $this->send_image($img);
- }
-
- /**
- * entropy
- */
- function policy_entropy($code)
+ function execute($code)
{
global $config;
- // Generate image
- $img_x = 800;
- $img_y = 250;
- $img = imagecreatetruecolor($img_x, $img_y);
-
- // Generate colors
- $c = new color_manager($img, array(
- 'random' => true,
- 'min_value' => 60,
- ), 'hsv');
+ $stats = gd_info();
- $scheme = $c->color_scheme('background', 'triadic', false);
- $scheme = $c->mono_range($scheme, 'both', 10, false);
- shuffle($scheme);
- $bg_colors = array_splice($scheme, mt_rand(6, 12));
-
- // Generate code characters
- $characters = $sizes = $bounding_boxes = array();
- $width_avail = $img_x;
- $code_num = sizeof($code);
-
- for ($i = 0; $i < $code_num; ++$i)
- {
- $char_class = $this->captcha_char();
- $characters[$i] = new $char_class($code[$i]);
-
- list($min, $max) = $characters[$i]->range();
- $sizes[$i] = mt_rand($min, $max);
- $box = $characters[$i]->dimensions($sizes[$i]);
- $width_avail -= ($box[2] - $box[0]);
- $bounding_boxes[$i] = $box;
- }
-
- // Redistribute leftover x-space
- $offset = array();
- for ($i = 0; $i < $code_num; ++$i)
+ if (substr($stats['GD Version'], 0, 7) === 'bundled')
{
- $denom = ($code_num - $i);
- $denom = max(1.5, $denom);
- $offset[$i] = mt_rand(0, (1.5 * $width_avail) / $denom);
- $width_avail -= $offset[$i];
+ $bundled = true;
}
-
- // Add some line noise
- if ($config['policy_entropy_noise_line'])
- {
- $this->noise_line($img, 0, 0, $img_x, $img_y, $c->r('background'), $scheme, $bg_colors);
- }
-
- // Draw the text
- $xoffset = 0;
- for ($i = 0; $i < $code_num; ++$i)
- {
- $dimm = $bounding_boxes[$i];
- $xoffset += ($offset[$i] - $dimm[0]);
- $yoffset = mt_rand(-$dimm[1], $img_y - $dimm[3]);
- $characters[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $c->r('background'), $scheme);
- $xoffset += $dimm[2];
- }
-
- // Add some pixel noise
- if ($config['policy_entropy_noise_pixel'])
+ else
{
- $this->noise_pixel($img, 0, 0, $img_x, $img_y, $c->r('background'), $scheme, $bg_colors, $config['policy_entropy_noise_pixel']);
+ $bundled = false;
}
- // Send image
- $this->send_image($img);
- }
-
- /**
- * 3dbitmap
- */
- function policy_3dbitmap($code)
- {
- // Generate image
- $img_x = 700;
- $img_y = 225;
- $img = imagecreatetruecolor($img_x, $img_y);
- $x_grid = mt_rand(6, 10);
- $y_grid = mt_rand(6, 10);
-
- // Ok, so lets cut to the chase. We could accurately represent this in 3d and
- // do all the appropriate linear transforms. my questions is... why bother?
- // The computational overhead is unnecessary when you consider the simple fact:
- // we're not here to accurately represent a model, but to just show off some random-ish
- // polygons
-
- // Conceive of 3 spaces.
- // 1) planar-space (discrete "pixel" grid)
- // 2) 3-space. (planar-space with z/height aspect)
- // 3) image space (pixels on the screen)
-
- // resolution of the planar-space we're embedding the text code in
- $plane_x = 90;
- $plane_y = 25;
-
- $subdivision_factor = 2;
-
- // $box is the 4 points in img_space that correspond to the corners of the plane in 3-space
- $box = array(array(), array(), array(), array());
-
- // Top left
- $box[0][0] = mt_rand(20, 40);
- $box[0][1] = mt_rand(40, 60);
-
- // Top right
- $box[1][0] = mt_rand($img_x - 80, $img_x - 60);
- $box[1][1] = mt_rand(10, 30);
-
- // Bottom right
- $box[2][0] = mt_rand($img_x - 40, $img_x - 20);
- $box[2][1] = mt_rand($img_y - 50, $img_y - 30);
-
- // Bottom left.
- // because we want to be able to make shortcuts in the 3d->2d,
- // we'll calculate the 4th point so that it forms a proper trapezoid
- $box[3][0] = $box[2][0] + $box[0][0] - $box[1][0];
- $box[3][1] = $box[2][1] + $box[0][1] - $box[1][1];
- $c = new color_manager($img, array(
- 'random' => true,
- 'min_saturation' => 50,
- 'min_value' => 65,
- ));
-
- $r1 = $c->random_color(array(
- 'min_value' => 20,
- 'max_value' => 50,
- ));
- $r2 = $c->random_color(array(
- 'min_value' => 70,
- 'max_value' => 100,
- ));
- $rdata = mt_rand(0,1) ? array(
- $c->colors[$r1],
- $c->colors[$r2],
- ) : array(
- $c->colors[$r2],
- $c->colors[$r1],
- );
-
- $colors = array();
- for ($i = 0; $i < 60; ++$i)
+ preg_match('/[\\d.]+/', $stats['GD Version'], $version);
+ if (version_compare($version[0], '2.0.1', '>='))
{
- $colors[$i - 30] = $c->allocate(array(
- $rdata[0][0],
- (($i * $rdata[0][1]) + ((60 - $i) * $rdata[1][1])) / 60,
- (($i * $rdata[0][2]) + ((60 - $i) * $rdata[1][2])) / 60,
- ));
+ $gd_version = 2;
}
-
- // $img_buffer is the last row of 3-space positions (converted to img-space), cached
- // (using this means we don't need to recalculate all 4 positions for each new polygon,
- // merely the newest point that we're adding, which is then cached.
- $img_buffer = array(array(), array());
-
- // In image-space, the x- and y-offset necessary to move one unit in the x-direction in planar-space
- $dxx = ($box[1][0] - $box[0][0]) / ($subdivision_factor * $plane_x);
- $dxy = ($box[1][1] - $box[0][1]) / ($subdivision_factor * $plane_x);
-
- // In image-space, the x- and y-offset necessary to move one unit in the y-direction in planar-space
- $dyx = ($box[3][0] - $box[0][0]) / ($subdivision_factor * $plane_y);
- $dyy = ($box[3][1] - $box[0][1]) / ($subdivision_factor * $plane_y);
-
- // Initial captcha-letter offset in planar-space
- $plane_offset_x = 2;
- $plane_offset_y = 5;
-
- // character map
- $map = captcha_bitmaps();
-
- // matrix
- $plane = array();
-
- // for each character, we'll silkscreen it into our boolean pixel plane
- for ($c = 0, $code_num = sizeof($code); $c < $code_num; ++$c)
+ else
{
- $letter = $code[$c];
-
- for ($x = $map['width'] - 1; $x >= 0; --$x)
- {
- for ($y = $map['height'] - 1; $y >= 0; --$y)
- {
- if ($map['data'][$letter][$y][$x])
- {
- $plane[$y + $plane_offset_y + (($c & 1) ? 1 : -1)][$x + $plane_offset_x] = true;
- }
- }
- }
- $plane_offset_x += 11;
+ $gd_version = 1;
}
- // calculate our first buffer, we can't actually draw polys with these yet
- // img_pos_prev == screen x,y location to our immediate left.
- // img_pos_cur == current screen x,y location
- // we calculate screen position of our
- // current cell based on the difference from the previous cell
- // rather than recalculating from absolute coordinates
- // What we cache into the $img_buffer contains the raised text coordinates.
- $img_pos_prev = $img_buffer[0][0] = $box[0];
- $cur_height = $prev_height = $this->wave_height(0, 0, $subdivision_factor);
- $full_x = $plane_x * $subdivision_factor;
- $full_y = $plane_y * $subdivision_factor;
+ // set dimension of image
+ $lx = 360;
+ $ly = 96;
- for ($x = 1; $x <= $full_x; ++$x)
+ // create the image, stay compat with older versions of GD
+ if ($gd_version === 2)
{
- $cur_height = $this->wave_height($x, 0, $subdivision_factor);
- $offset = $cur_height - $prev_height;
- $img_pos_cur = array($img_pos_prev[0] + $dxx,
- $img_pos_prev[1] + $dxy + $offset);
-
- $img_buffer[0][$x] = $img_pos_cur;
- $img_pos_prev = $img_pos_cur;
- $prev_height = $cur_height;
+ $func1 = 'imagecreatetruecolor';
+ $func2 = 'imagecolorallocate';
}
-
- for ($y = 1; $y <= $full_y; ++$y)
+ else
{
- // swap buffers
- $buffer_cur = $y & 1;
- $buffer_prev = 1 - $buffer_cur;
-
- $prev_height = $this->wave_height(0, $y, $subdivision_factor);
- $offset = $prev_height - $this->wave_height(0, $y - 1, $subdivision_factor);
- $img_pos_cur = array($img_buffer[$buffer_prev][0][0] + $dyx,
- $img_buffer[$buffer_prev][0][1] + $dyy + $offset);
- $img_pos_prev = $img_pos_cur;
-
- $img_buffer[$buffer_cur][0] = $img_pos_cur;
-
- for ($x = 1; $x <= $full_x; ++$x)
- {
- $cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, 1, $x_grid, $y_grid);
-
- //height is a z-factor, not a y-factor
- $offset = $cur_height - $prev_height;
- $img_pos_cur = array($img_pos_prev[0] + $dxx,
- $img_pos_prev[1] + $dxy + $offset);
-
- //(height is float, index it to an int, get closest color)
- $color = $colors[intval($cur_height)];
- $img_pos_prev = $img_pos_cur;
- $prev_height = $cur_height;
-
- $y_index_old = intval(($y - 1) / $subdivision_factor);
- $y_index_new = intval($y / $subdivision_factor);
- $x_index_old = intval(($x - 1) / $subdivision_factor);
- $x_index_new = intval($x / $subdivision_factor);
-
- if (!empty($plane[$y_index_new][$x_index_new]))
- {
- $offset2 = $this->wave_height($x, $y, $subdivision_factor, 1) - 30 - $cur_height;
- $img_pos_cur[1] += $offset2;
- $color = $colors[20];
- }
- $img_buffer[$buffer_cur][$x] = $img_pos_cur;
-
- // Smooth the edges as much as possible by having not more than one low<->high traingle per square
- // Otherwise, just
- $diag_down = (empty($plane[$y_index_old][$x_index_old]) == empty($plane[$y_index_new][$x_index_new]));
- $diag_up = (empty($plane[$y_index_old][$x_index_new]) == empty($plane[$y_index_new][$x_index_old]));
-
- // natural switching
- $mode = ($x + $y) & 1;
-
- // override if it requires it
- if ($diag_down != $diag_up)
- {
- $mode = $diag_up;
- }
-
- if ($mode)
- {
- // +-/ /
- // 1 |/ 2 /|
- // / /-+
- $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x]);
- $poly2 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_cur][$x], $img_buffer[$buffer_prev][$x]);
- }
- else
- {
- // \ \-+
- // 1 |\ 2 \|
- // +-\ \
- $poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_cur][$x]);
- $poly2 = array_merge($img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x], $img_buffer[$buffer_cur][$x]);
- }
-
- imagefilledpolygon($img, $poly1, 3, $color);
- imagefilledpolygon($img, $poly2, 3, $color);
- }
+ $func1 = 'imagecreate';
+ $func2 = 'imagecolorclosest';
}
- // Send image on it's merry way
- $this->send_image($img);
- }
+ $image = $func1($lx, $ly);
- /**
- * overlap
- */
- function policy_overlap($code)
- {
- global $config;
- $char_size = 40;
- $overlap_factor = .32;
-
- // Generate image
- $img_x = 250;
- $img_y = 120;
- $img = imagecreatetruecolor($img_x, $img_y);
-
- // Generate colors
- $c = new color_manager($img, array(
- 'random' => true,
- 'min_saturation' => 70,
- 'min_value' => 65,
- ));
-
- $primaries = $c->color_scheme('background', 'triadic', false);
- $text = mt_rand(0, 1);
- $c->name_color('text', $primaries[$text]);
- $noise = $c->mono_range($primaries[1 - $text], 'both', 6, false);
-
- // Generate code characters
- $characters = $bounding_boxes = array();
- $width_avail = $img_x;
-
- // Get the character rendering scheme
- $char_class = $this->captcha_char('char_ttf');
- $code_num = sizeof($code);
-
- for ($i = 0; $i < $code_num; ++$i)
+ if ($bundled)
{
- $characters[$i] = new $char_class($code[$i], array('angle' => 0));
- $box = $characters[$i]->dimensions($char_size);
- $width_avail -= ((1 - $overlap_factor) * ($box[2] - $box[0]));
- $bounding_boxes[$i] = $box;
+ imageantialias($image, true);
}
- // Redistribute leftover x-space
- $offset = mt_rand(0, $width_avail);
-
- // Add some line noise
- if ($config['policy_overlap_noise_line'])
- {
- $this->noise_line($img, 0, 0, $img_x, $img_y, $c->r('background'), array($c->r('text')), $noise);
- }
+ // set background color
+ $back = imagecolorallocate($image, mt_rand(224, 255), mt_rand(224, 255), mt_rand(224, 255));
+ imagefilledrectangle($image, 0, 0, $lx, $ly, $back);
- // Draw the text
- $min = 10 - $bounding_boxes[0][1];
- $max = ($img_y - 10) - $bounding_boxes[0][3];
- $med = ($max + $min) / 2;
-
- $yoffset = mt_rand($med, $max);
- $char_num = sizeof($characters);
-
- imagesetthickness($img, 3);
- for ($i = 0; $i < $char_num; ++$i)
+ // allocates the 216 websafe color palette to the image
+ if ($gd_version === 1)
{
- if ($i)
+ for ($r = 0; $r <= 255; $r += 51)
{
- imageline($img, $old_x + mt_rand(-3, 3), $old_y - 70 + mt_rand(-3, 3), $offset + mt_rand(-3, 3), $yoffset - 70 + mt_rand(-3, 3), $c->r('text'));
- imageline($img, $old_x + mt_rand(-3, 3), $old_y + 30 + mt_rand(-3, 3), $offset + mt_rand(-3, 3), $yoffset + 30 + mt_rand(-3, 3), $c->r('text'));
- }
-
- $dimm = $bounding_boxes[$i];
- $offset -= $dimm[0];
- $characters[$i]->drawchar($char_size, $offset, $yoffset, $img, $c->r('background'), array($c->r('text')));
-
- $old_x = $offset;
- $old_y = $yoffset;
-
- $offset += $dimm[2];
- $offset -= (($dimm[2] - $dimm[0]) * $overlap_factor);
- $yoffset += ($i & 1) ? ((1 - $overlap_factor) * ($dimm[3] - $dimm[1])) : ((1 - $overlap_factor) * ($dimm[1] - $dimm[3]));
- }
-
- imagesetthickness($img, 1);
-
- // Add some medium pixel noise
- if ($config['policy_overlap_noise_pixel'])
- {
- $this->noise_pixel($img, 0, 0, $img_x, $img_y, $c->r('background'), array($c->r('text')), $noise, $config['policy_overlap_noise_pixel']);
- }
-
- // Send image
- $this->send_image($img);
- }
-
- /**
- * Noise pixel
- */
- function noise_pixel($img, $min_x, $min_y, $max_x, $max_y, $bg, $font, $non_font, $override = false)
- {
- $noise_modules = array('noise_pixel_light', 'noise_pixel_medium', 'noise_pixel_heavy');
-
- if ($override == false)
- {
- $override = array_rand($override);
- }
-
- // Use the module $override, else a random picked one...
- $module = $noise_modules[intval($override) - 1];
-
- switch ($module)
- {
- case 'noise_pixel_light':
-
- for ($x = $min_x; $x < $max_x; $x += mt_rand(9, 18))
+ for ($g = 0; $g <= 255; $g += 51)
{
- for ($y = $min_y; $y < $max_y; $y += mt_rand(4, 9))
+ for ($b = 0; $b <= 255; $b += 51)
{
- imagesetpixel($img, $x, $y, $non_font[array_rand($non_font)]);
+ imagecolorallocate($image, $r, $g, $b);
}
}
-
- for ($y = $min_y; $y < $max_y; $y += mt_rand(9, 18))
- {
- for ($x = $min_x; $x < $max_x; $x += mt_rand(4, 9))
- {
- imagesetpixel($img, $x, $y, $non_font[array_rand($non_font)]);
- }
- }
-
- break;
-
- case 'noise_pixel_medium':
-
- for ($x = $min_x; $x < $max_x; $x += mt_rand(4, 9))
- {
- for ($y = $min_y; $y < $max_y; $y += mt_rand(2, 5))
- {
- imagesetpixel($img, $x, $y, $non_font[array_rand($non_font)]);
- }
- }
-
- for ($y = $min_y; $y < $max_y; $y += mt_rand(4, 9))
- {
- for ($x = $min_x; $x < $max_x; $x += mt_rand(2, 5))
- {
- imagesetpixel($img, $x, $y, $non_font[array_rand($non_font)]);
- }
- }
-
- break;
-
- case 'noise_pixel_heavy':
-
- for ($x = $min_x; $x < $max_x; $x += mt_rand(4, 9))
- {
- for ($y = $min_y; $y < $max_y; $y++)
- {
- imagesetpixel($img, $x, $y, $non_font[array_rand($non_font)]);
- }
- }
-
- for ($y = $min_y; $y < $max_y; $y+= mt_rand(4, 9))
- {
- for ($x = $min_x; $x < $max_x; $x++)
- {
- imagesetpixel($img, $x, $y, $non_font[array_rand($non_font)]);
- }
- }
-
- break;
- }
- }
-
- /**
- * Noise line
- */
- function noise_line($img, $min_x, $min_y, $max_x, $max_y, $bg, $font, $non_font)
- {
- imagesetthickness($img, 2);
- $x1 = $min_x;
- $x2 = $max_x;
- $y1 = $min_y;
- $y2 = $min_y;
-
- do
- {
- $line = array_merge(
- array_fill(0, mt_rand(30, 60), $non_font[array_rand($non_font)]),
- array_fill(0, mt_rand(30, 60), $bg)
- );
-
- imagesetstyle($img, $line);
- imageline($img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
-
- $y1 += mt_rand(12, 35);
- $y2 += mt_rand(12, 35);
- }
- while ($y1 < $max_y && $y2 < $max_y);
-
- $x1 = $min_x;
- $x2 = $min_x;
- $y1 = $min_y;
- $y2 = $max_y;
-
- do
- {
- $line = array_merge(
- array_fill(0, mt_rand(30, 60), $non_font[array_rand($non_font)]),
- array_fill(0, mt_rand(30, 60), $bg)
- );
-
- imagesetstyle($img, $line);
- imageline($img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
-
- $x1 += mt_rand(12, 35);
- $x2 += mt_rand(12, 35);
- }
- while ($x1 < $max_x && $x2 < $max_x);
- imagesetthickness($img, 1);
- }
-
- /**
- * Randomly determine which char class to use
- * Able to define static one with override
- */
- function captcha_char($override = false)
- {
- static $character_classes = array();
-
- // Some people have GD but no TTF support
- if (sizeof($character_classes) == 0)
- {
- $character_classes = array('char_vector', 'char_hatches', 'char_cube3d', 'char_dots');
-
- if (function_exists('imagettfbbox') && function_exists('imagettftext'))
- {
- $character_classes[] = 'char_ttf';
- }
- }
-
- // Use the module $override, else a random picked one...
- $class = ($override !== false && in_array($override, $character_classes)) ? $override : $character_classes[array_rand($character_classes)];
-
- return $class;
- }
-}
-
-/**
-* @package VC
-*/
-class char_dots
-{
- var $vectors;
- var $space;
- var $radius;
- var $letter;
- var $width_percent;
-
- /**
- * Constuctor
- */
- function char_dots($letter = '', $args = false)
- {
- $width_percent = false;
- if (is_array($args))
- {
- $width_percent = (!empty($args['width_percent'])) ? $args['width_percent'] : false;
- }
-
- $this->vectors = captcha_vectors();
- $this->width_percent = (!empty($width_percent)) ? max(25, min(150, intval($width_percent))) : mt_rand(60, 90);
-
- $this->space = 10;
- $this->radius = 3;
- $this->density = 3;
- $this->letter = $letter;
- }
-
- /**
- * Draw a character
- */
- function drawchar($scale, $xoff, $yoff, $img, $background, $colors)
- {
- $vectorset = $this->vectors[$this->letter];
- $height = $scale;
- $width = (($scale * $this->width_percent) / 100);
- $color = $colors[array_rand($colors)];
-
- if (sizeof($vectorset))
- {
- foreach ($vectorset as $veclist)
- {
- switch ($veclist[0])
- {
- case 'line':
-
- $dx = ($veclist[3] - $veclist[1]) * $width;
- $dy = ($veclist[4] - $veclist[2]) * -$height;
-
- $len = sqrt(($dx * $dx) + ($dy * $dy));
-
- $inv_dx = -($dy / $len);
- $inv_dy = ($dx / $len);
-
- for ($i = 0; $i < $len; ++$i)
- {
- for ($k = 0; $k <= $this->density; ++$k)
- {
- $shift = mt_rand(-$this->radius, $this->radius);
- imagesetpixel($img,
- $xoff + ($veclist[1] * $width) + (($i * $dx) / $len) + ($inv_dx * $shift),
- $yoff + ((1 - $veclist[2]) * $height) + (($i * $dy) / $len) + ($inv_dy * $shift),
- $color);
- }
- }
-
- break;
-
- case 'arc':
-
- $arclengthdeg = $veclist[6] - $veclist[5];
- $arclengthdeg += ( $arclengthdeg < 0 ) ? 360 : 0;
-
- $arclength = ((($veclist[3] * $width) + ($veclist[4] * $height)) * M_PI) / 2;
-
- $arclength = ($arclength * $arclengthdeg) / 360;
-
- $x_c = $veclist[1] * $width;
- $y_c = (1 - $veclist[2]) * $height;
- $increment = ($arclengthdeg / $arclength);
-
- for ($i = 0; $i < $arclengthdeg; $i += $increment)
- {
- $theta = deg2rad(($i + $veclist[5]) % 360);
- $x_o = cos($theta);
- $y_o = sin($theta);
- $pre_width = ($veclist[3] * 0.5 * $width);
- $pre_height = ($veclist[4] * 0.5 * $height);
- for ($k = 0; $k <= $this->density; ++$k)
- {
- $shift = mt_rand(-$this->radius, $this->radius);
- $x_o1 = $x_o * ($pre_width + $shift);
- $y_o1 = $y_o * ($pre_height + $shift);
- imagesetpixel($img,
- $xoff + $x_c + $x_o1,
- $yoff + $y_c + $y_o1,
- $color);
- }
- }
-
- break;
-
- default:
- // Do nothing with bad input
- break;
- }
}
}
- }
-
- /*
- * return a roughly acceptable range of sizes for rendering with this texttype
- */
- function range()
- {
- return array(60, 80);
- }
- /**
- * dimensions
- */
- function dimensions($size)
- {
- return array(-4, -4, (($size * $this->width_percent) / 100) + 4, $size + 4);
- }
-}
-/**
-* @package VC
-*/
-class char_vector
-{
- var $vectors;
- var $width_percent;
- var $letter;
-
- /**
- * Constructor
- */
- function char_vector($letter = '', $args = false)
- {
- $width_percent = false;
- if (is_array($args))
- {
- $width_percent = (!empty($args['width_percent'])) ? $args['width_percent'] : false;
- }
-
- $this->vectors = captcha_vectors();
- $this->width_percent = (!empty($width_percent)) ? max(25, min(150, intval($width_percent))) : mt_rand(60,90);
- $this->letter = $letter;
- }
-
- /**
- * Draw a character
- */
- function drawchar($scale, $xoff, $yoff, $img, $background, $colors)
- {
- $vectorset = $this->vectors[$this->letter];
- $height = $scale;
- $width = (($scale * $this->width_percent) / 100);
- $color = $colors[array_rand($colors)];
-
- if (sizeof($vectorset))
+ // fill with noise or grid
+ if ($config['captcha_gd_noise'])
{
- foreach ($vectorset as $veclist)
+ // random characters in background with random position, angle, color
+ for ($i = 0 ; $i < 72; $i++)
{
- for ($i = 0; $i < 9; ++$i)
- {
- $xp = $i % 3;
- $yp = ($i - $xp) / 3;
- $xp--;
- $yp--;
-
- switch ($veclist[0])
- {
- case 'line':
- imageline($img,
- $xoff + $xp + ($veclist[1] * $width),
- $yoff + $yp + ((1 - $veclist[2]) * $height),
- $xoff + $xp + ($veclist[3] * $width),
- $yoff + $yp + ((1 - $veclist[4]) * $height),
- $color
- );
- break;
-
- case 'arc':
- imagearc($img,
- $xoff + $xp + ($veclist[1] * $width),
- $yoff + $yp + ((1 - $veclist[2]) * $height),
- $veclist[3] * $width,
- $veclist[4] * $height,
- $veclist[5],
- $veclist[6],
- $color
- );
- break;
- }
- }
+ $size = mt_rand(8, 23);
+ $angle = mt_rand(0, 360);
+ $x = mt_rand(0, 360);
+ $y = mt_rand(0, (int)($ly - ($size / 5)));
+ $color = $func2($image, mt_rand(160, 224), mt_rand(160, 224), mt_rand(160, 224));
+ $text = chr(mt_rand(45, 250));
+ imagettftext($image, $size, $angle, $x, $y, $color, $this->get_font(), $text);
}
}
- }
-
- /*
- * return a roughly acceptable range of sizes for rendering with this texttype
- */
- function range()
- {
- return array(50, 80);
- }
-
- /**
- * dimensions
- */
- function dimensions($size)
- {
- return array(-2, -2, (($size * $this->width_percent) / 100 ) + 2, $size + 2);
- }
-}
-
-/**
-* @package VC
-*/
-class char_ttf
-{
- var $angle = 0;
- var $fontfile = '';
- var $letter = '';
-
- /**
- * Constructor
- */
- function char_ttf($letter = '', $args = false)
- {
- $font = $angle = false;
-
- if (is_array($args))
- {
- $font = (!empty($args['font'])) ? $args['font'] : false;
- $angle = (isset($args['angle'])) ? $args['angle'] : false;
- }
-
- $fonts = captcha_load_ttf_fonts();
-
- if (empty($font) || !isset($fonts[$font]))
- {
- $font = array_rand($fonts);
- }
-
- $this->fontfile = $fonts[$font];
- $this->angle = ($angle !== false) ? intval($angle) : mt_rand(-40, 40);
- $this->letter = $letter;
- }
-
- /**
- * Draw a character
- */
- function drawchar($scale, $xoff, $yoff, $img, $background, $colors)
- {
- $color = $colors[array_rand($colors)];
- imagettftext($img, $scale, $this->angle, $xoff, $yoff, $color, $this->fontfile, $this->letter);
- }
-
- /*
- * return a roughly acceptable range of sizes for rendering with this texttype
- */
- function range()
- {
- return array(36, 150);
- }
-
- /**
- * Dimensions
- */
- function dimensions($scale)
- {
- $data = imagettfbbox($scale, $this->angle, $this->fontfile, $this->letter);
- return ($this->angle > 0) ? array($data[6], $data[5], $data[2], $data[1]) : array($data[0], $data[7], $data[4], $data[3]);
- }
-}
-
-/**
-* @package VC
-*/
-class char_hatches
-{
- var $vectors;
- var $space;
- var $radius;
- var $letter;
-
- /**
- * Constructor
- */
- function char_hatches($letter = '', $args = false)
- {
- $width_percent = false;
- if (is_array($args))
- {
- $width_percent = (!empty($args['width_percent'])) ? $args['width_percent'] : false;
- }
-
- $this->vectors = captcha_vectors();
- $this->width_percent = (!empty($width_percent)) ? max(25, min(150, intval($width_percent))) : mt_rand(60, 90);
-
- $this->space = 10;
- $this->radius = 3;
- $this->letter = $letter;
- }
-
- /**
- * Draw a character
- */
- function drawchar($scale, $xoff, $yoff, $img, $background, $colors)
- {
- $vectorset = $this->vectors[$this->letter];
- $height = $scale;
- $width = (($scale * $this->width_percent) / 100);
- $color = $colors[array_rand($colors)];
-
- if (sizeof($vectorset))
+ else
{
- foreach ($vectorset as $veclist)
+ // generate grid
+ for ($i = 0; $i < $lx; $i += 13)
{
- switch ($veclist[0])
- {
- case 'line':
- $dx = ($veclist[3] - $veclist[1]) * $width;
- $dy = ($veclist[4] - $veclist[2]) * -$height;
-
- $idx = -$dy;
- $idy = $dx;
-
- $length = sqrt(pow($dx, 2) + pow($dy, 2));
-
- $hatches = $length / $this->space;
-
- for ($p = 0; $p <= $hatches; ++$p)
- {
- if (!$p && !mt_rand(0, 9) && ($hatches > 3))
- {
- continue;
- }
-
- $xp = 1;
- $yp = -2;
- for ($i = 0; $i < 9; ++$i)
- {
- $xp += !($i % 3) ? -2 : 1;
- $yp += !($i % 3) ? 1 : 0;
-
- $x_o = ((($p * $veclist[1]) + (($hatches - $p) * $veclist[3])) * $width ) / $hatches;
- $y_o = $height - (((($p * $veclist[2]) + (($hatches - $p) * $veclist[4])) * $height ) / $hatches);
- $x_1 = $xoff + $xp + $x_o;
- $y_1 = $yoff + $yp + $y_o;
-
- $x_d1 = (($dx - $idx) * $this->radius) / $length;
- $y_d1 = (($dy - $idy) * $this->radius) / $length;
-
- $x_d2 = (($dx - $idx) * -$this->radius) / $length;
- $y_d2 = (($dy - $idy) * -$this->radius) / $length;
-
- imageline($img, $x_1 + $x_d1, $y_1 + $y_d1, $x_1 + $x_d2, $y_1 + $y_d2, $color);
- }
- }
- break;
-
- case 'arc':
- $arclengthdeg = $veclist[6] - $veclist[5];
- $arclengthdeg += ( $arclengthdeg < 0 ) ? 360 : 0;
-
- $arclength = ((($veclist[3] * $width) + ($veclist[4] * $height)) * M_PI) / 2;
- $arclength = ($arclength * $arclengthdeg) / 360;
-
- $hatches = $arclength / $this->space;
-
- $hatchdeg = ($arclengthdeg * $this->space) / $arclength;
- $shiftdeg = ($arclengthdeg * $this->radius) / $arclength;
-
- $x_c = $veclist[1] * $width;
- $y_c = (1 - $veclist[2]) * $height;
-
- for ($p = 0; $p <= $arclengthdeg; $p += $hatchdeg)
- {
- if (!mt_rand(0, 9) && ($hatches > 3) && !$p)
- {
- continue;
- }
-
- $theta1 = deg2rad(($p + $veclist[5] - $shiftdeg) % 360);
- $theta2 = deg2rad(($p + $veclist[5] + $shiftdeg) % 360);
- $x_o1 = cos($theta1) * (($veclist[3] * 0.5 * $width) - $this->radius);
- $y_o1 = sin($theta1) * (($veclist[4] * 0.5 * $height) - $this->radius);
- $x_o2 = cos($theta2) * (($veclist[3] * 0.5 * $width) + $this->radius);
- $y_o2 = sin($theta2) * (($veclist[4] * 0.5 * $height) + $this->radius);
-
- $xp = 1;
- $yp = -2;
- for ($i = 0; $i < 9; ++$i)
- {
- $xp += !($i % 3) ? -2 : 1;
- $yp += !($i % 3) ? 1 : 0;
-
- imageline($img,
- $xoff + $xp + $x_c + $x_o1,
- $yoff + $yp + $y_c + $y_o1,
- $xoff + $xp + $x_c + $x_o2,
- $yoff + $yp + $y_c + $y_o2,
- $color
- );
- }
- }
- break;
- }
+ $color = $func2($image, mt_rand(160, 224), mt_rand(160, 224), mt_rand(160, 224));
+ imageline($image, $i, 0, $i, $ly, $color);
}
- }
- }
-
- /*
- * return a roughly acceptable range of sizes for rendering with this texttype
- */
- function range()
- {
- return array(60, 80);
- }
-
- /**
- * Dimensions
- */
- function dimensions($size)
- {
- return array(-4, -4, (($size * $this->width_percent) / 100) + 4, $size + 4);
- }
-}
-
-/**
-* @package VC
-*/
-class char_cube3d
-{
- // need to abstract out the cube3d from the cubechar
- var $bitmaps;
-
- var $basis_matrix = array(array(1, 0, 0), array(0, 1, 0), array(0, 0, 1));
- var $abs_x = array(1, 0);
- var $abs_y = array(0, 1);
- var $x = 0;
- var $y = 1;
- var $z = 2;
- var $letter = '';
-
- function char_cube3d($letter)
- {
- $this->bitmaps = captcha_bitmaps();
-
- $this->basis_matrix[0][0] = mt_rand(-600, 600);
- $this->basis_matrix[0][1] = mt_rand(-600, 600);
- $this->basis_matrix[0][2] = (mt_rand(0, 1) * 2000) - 1000;
- $this->basis_matrix[1][0] = mt_rand(-1000, 1000);
- $this->basis_matrix[1][1] = mt_rand(-1000, 1000);
- $this->basis_matrix[1][2] = mt_rand(-1000, 1000);
-
- $this->normalize($this->basis_matrix[0]);
- $this->normalize($this->basis_matrix[1]);
- $this->basis_matrix[2] = $this->cross_product($this->basis_matrix[0], $this->basis_matrix[1]);
- $this->normalize($this->basis_matrix[2]);
-
- // $this->basis_matrix[1] might not be (probably isn't) orthogonal to $basis_matrix[0]
- $this->basis_matrix[1] = $this->cross_product($this->basis_matrix[0], $this->basis_matrix[2]);
- $this->normalize($this->basis_matrix[1]);
-
- // Make sure our cube is facing into the canvas (assuming +z == in)
- for ($i = 0; $i < 3; ++$i)
- {
- if ($this->basis_matrix[$i][2] < 0)
+ for ($i = 0; $i < $ly; $i += 11)
{
- $this->basis_matrix[$i][0] *= -1;
- $this->basis_matrix[$i][1] *= -1;
- $this->basis_matrix[$i][2] *= -1;
+ $color = $func2($image, mt_rand(160, 224), mt_rand(160, 224), mt_rand(160, 224));
+ imageline($image, 0, $i, $lx, $i, $color);
}
}
- // Force our "z" basis vector to be the one with greatest absolute z value
- $this->x = 0;
- $this->y = 1;
- $this->z = 2;
+ $len = strlen($code);
- // Swap "y" with "z"
- if ($this->basis_matrix[1][2] > $this->basis_matrix[2][2])
+ for ($i = 0, $x = mt_rand(20, 40); $i < $len; $i++)
{
- $this->z = 1;
- $this->y = 2;
- }
+ $text = strtoupper($code[$i]);
+ $angle = mt_rand(-30, 30);
+ $size = mt_rand(20, 40);
+ $y = mt_rand((int)($size * 1.5), (int)($ly - ($size / 7)));
- // Swap "x" with "z"
- if ($this->basis_matrix[0][2] > $this->basis_matrix[$this->z][2])
- {
- $this->x = $this->z;
- $this->z = 0;
- }
+ $color = $func2($image, mt_rand(0, 127), mt_rand(0, 127), mt_rand(0, 127));
+ $shadow = $func2($image, mt_rand(127, 254), mt_rand(127, 254), mt_rand(127, 254));
+ $font = $this->get_font();
- // Still need to determine which of $x,$y are which.
- // wrong orientation if y's y-component is less than it's x-component
- // likewise if x's x-component is less than it's y-component
- // if they disagree, go with the one with the greater weight difference.
- // rotate if positive
- $weight = (abs($this->basis_matrix[$this->x][1]) - abs($this->basis_matrix[$this->x][0])) +
- (abs($this->basis_matrix[$this->y][0]) - abs($this->basis_matrix[$this->y][1]));
+ imagettftext($image, $size, $angle, $x + (int)($size / 15), $y, $shadow, $font, $text);
+ imagettftext($image, $size, $angle, $x, $y - (int)($size / 15), $color, $font, $text);
- // Swap "x" with "y"
- if ($weight > 0)
- {
- list($this->x, $this->y) = array($this->y, $this->x);
+ $x += $size + 4;
}
- $this->abs_x = array($this->basis_matrix[$this->x][0], $this->basis_matrix[$this->x][1]);
- $this->abs_y = array($this->basis_matrix[$this->y][0], $this->basis_matrix[$this->y][1]);
-
- if ($this->abs_x[0] < 0)
- {
- $this->abs_x[0] *= -1;
- $this->abs_x[1] *= -1;
- }
-
- if ($this->abs_y[1] > 0)
- {
- $this->abs_y[0] *= -1;
- $this->abs_y[1] *= -1;
- }
-
- $this->letter = $letter;
- }
-
- /**
- *
- */
- function draw($im, $scale, $xoff, $yoff, $face, $xshadow, $yshadow)
- {
- $origin = array(0, 0, 0);
- $xvec = $this->scale($this->basis_matrix[$this->x], $scale);
- $yvec = $this->scale($this->basis_matrix[$this->y], $scale);
- $face_corner = $this->sum2($xvec, $yvec);
-
- $zvec = $this->scale($this->basis_matrix[$this->z], $scale);
- $x_corner = $this->sum2($xvec, $zvec);
- $y_corner = $this->sum2($yvec, $zvec);
-
- imagefilledpolygon($im, $this->gen_poly($xoff, $yoff, $origin, $xvec, $x_corner, $zvec), 4, $yshadow);
- imagefilledpolygon($im, $this->gen_poly($xoff, $yoff, $origin, $yvec, $y_corner, $zvec), 4, $xshadow);
- imagefilledpolygon($im, $this->gen_poly($xoff, $yoff, $origin, $xvec, $face_corner, $yvec), 4, $face);
- }
-
- /**
- * Draw a character
- */
- function drawchar($scale, $xoff, $yoff, $img, $background, $colors)
- {
- $width = $this->bitmaps['width'];
- $height = $this->bitmaps['height'];
- $bitmap = $this->bitmaps['data'][$this->letter];
-
- $color1 = $colors[array_rand($colors)];
- $color2 = $colors[array_rand($colors)];
-
- $swapx = ($this->basis_matrix[$this->x][0] > 0);
- $swapy = ($this->basis_matrix[$this->y][1] < 0);
-
- for ($y = 0; $y < $height; ++$y)
- {
- for ($x = 0; $x < $width; ++$x)
- {
- $xp = ($swapx) ? ($width - $x - 1) : $x;
- $yp = ($swapy) ? ($height - $y - 1) : $y;
-
- if ($bitmap[$height - $yp - 1][$xp])
- {
- $dx = $this->scale($this->abs_x, ($xp - ($swapx ? ($width / 2) : ($width / 2) - 1)) * $scale);
- $dy = $this->scale($this->abs_y, ($yp - ($swapy ? ($height / 2) : ($height / 2) - 1)) * $scale);
- $xo = $xoff + $dx[0] + $dy[0];
- $yo = $yoff + $dx[1] + $dy[1];
-
- $origin = array(0, 0, 0);
- $xvec = $this->scale($this->basis_matrix[$this->x], $scale);
- $yvec = $this->scale($this->basis_matrix[$this->y], $scale);
- $face_corner = $this->sum2($xvec, $yvec);
-
- $zvec = $this->scale($this->basis_matrix[$this->z], $scale);
- $x_corner = $this->sum2($xvec, $zvec);
- $y_corner = $this->sum2($yvec, $zvec);
-
- imagefilledpolygon($img, $this->gen_poly($xo, $yo, $origin, $xvec, $x_corner,$zvec), 4, $color1);
- imagefilledpolygon($img, $this->gen_poly($xo, $yo, $origin, $yvec, $y_corner,$zvec), 4, $color2);
-
- $face = $this->gen_poly($xo, $yo, $origin, $xvec, $face_corner, $yvec);
-
- imagefilledpolygon($img, $face, 4, $background);
- imagepolygon($img, $face, 4, $color1);
- }
- }
- }
- }
-
- /*
- * return a roughly acceptable range of sizes for rendering with this texttype
- */
- function range()
- {
- return array(5, 10);
- }
-
- /**
- * Vector length
- */
- function vectorlen($vector)
- {
- return sqrt(pow($vector[0], 2) + pow($vector[1], 2) + pow($vector[2], 2));
- }
-
- /**
- * Normalize
- */
- function normalize(&$vector, $length = 1)
- {
- $length = (( $length < 1) ? 1 : $length);
- $length /= $this->vectorlen($vector);
- $vector[0] *= $length;
- $vector[1] *= $length;
- $vector[2] *= $length;
- }
-
- /**
- *
- */
- function cross_product($vector1, $vector2)
- {
- $retval = array(0, 0, 0);
- $retval[0] = (($vector1[1] * $vector2[2]) - ($vector1[2] * $vector2[1]));
- $retval[1] = -(($vector1[0] * $vector2[2]) - ($vector1[2] * $vector2[0]));
- $retval[2] = (($vector1[0] * $vector2[1]) - ($vector1[1] * $vector2[0]));
-
- return $retval;
- }
-
- /**
- *
- */
- function sum($vector1, $vector2)
- {
- return array($vector1[0] + $vector2[0], $vector1[1] + $vector2[1], $vector1[2] + $vector2[2]);
- }
-
- /**
- *
- */
- function sum2($vector1, $vector2)
- {
- return array($vector1[0] + $vector2[0], $vector1[1] + $vector2[1]);
- }
-
- /**
- *
- */
- function scale($vector, $length)
- {
- if (sizeof($vector) == 2)
- {
- return array($vector[0] * $length, $vector[1] * $length);
- }
-
- return array($vector[0] * $length, $vector[1] * $length, $vector[2] * $length);
- }
-
- /**
- *
- */
- function gen_poly($xoff, $yoff, &$vec1, &$vec2, &$vec3, &$vec4)
- {
- $poly = array();
- $poly[0] = $xoff + $vec1[0];
- $poly[1] = $yoff + $vec1[1];
- $poly[2] = $xoff + $vec2[0];
- $poly[3] = $yoff + $vec2[1];
- $poly[4] = $xoff + $vec3[0];
- $poly[5] = $yoff + $vec3[1];
- $poly[6] = $xoff + $vec4[0];
- $poly[7] = $yoff + $vec4[1];
-
- return $poly;
- }
-
- /**
- * dimensions
- */
- function dimensions($size)
- {
- $xn = $this->scale($this->basis_matrix[$this->x], -($this->bitmaps['width'] / 2) * $size);
- $xp = $this->scale($this->basis_matrix[$this->x], ($this->bitmaps['width'] / 2) * $size);
- $yn = $this->scale($this->basis_matrix[$this->y], -($this->bitmaps['height'] / 2) * $size);
- $yp = $this->scale($this->basis_matrix[$this->y], ($this->bitmaps['height'] / 2) * $size);
-
- $p = array();
- $p[0] = $this->sum2($xn, $yn);
- $p[1] = $this->sum2($xp, $yn);
- $p[2] = $this->sum2($xp, $yp);
- $p[3] = $this->sum2($xn, $yp);
-
- $min_x = $max_x = $p[0][0];
- $min_y = $max_y = $p[0][1];
-
- for ($i = 1; $i < 4; ++$i)
- {
- $min_x = ($min_x > $p[$i][0]) ? $p[$i][0] : $min_x;
- $min_y = ($min_y > $p[$i][1]) ? $p[$i][1] : $min_y;
- $max_x = ($max_x < $p[$i][0]) ? $p[$i][0] : $max_x;
- $max_y = ($max_y < $p[$i][1]) ? $p[$i][1] : $max_y;
- }
-
- return array($min_x, $min_y, $max_x, $max_y);
- }
-}
-
-/**
-* Return bitmaps
-*/
-function captcha_bitmaps()
-{
- return array(
- 'width' => 9,
- 'height' => 15,
- 'data' => array(
- 'A' => array(
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(0,1,0,0,0,0,0,1,0),
- array(0,1,1,1,1,1,1,1,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- ),
- 'B' => array(
- array(1,1,1,1,1,1,1,0,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,1,0),
- array(1,1,1,1,1,1,1,0,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,1,0),
- array(1,1,1,1,1,1,1,0,0),
- ),
- 'C' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- 'D' => array(
- array(1,1,1,1,1,1,1,0,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,1,0),
- array(1,1,1,1,1,1,1,0,0),
- ),
- 'E' => array(
- array(1,1,1,1,1,1,1,1,1),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,1,1,1,1,1,1,1,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,1,1,1,1,1,1,1,1),
- ),
- 'F' => array(
- array(1,1,1,1,1,1,1,1,1),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,1,1,1,1,1,1,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- ),
- 'G' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,1,1,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- 'H' => array(
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,1,1,1,1,1,1,1,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- ),
- 'I' => array(
- array(1,1,1,1,1,1,1,1,1),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(1,1,1,1,1,1,1,1,1),
- ),
- 'J' => array(
- array(1,1,1,1,1,1,1,1,1),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(1,0,0,0,0,1,0,0,0),
- array(1,0,0,0,0,1,0,0,0),
- array(0,1,0,0,1,0,0,0,0),
- array(0,0,1,1,0,0,0,0,0),
- ),
- 'K' => array( // New 'K', supplied by NeoThermic
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,1,0,0),
- array(1,0,0,0,0,1,0,0,0),
- array(1,0,0,0,1,0,0,0,0),
- array(1,0,0,1,0,0,0,0,0),
- array(1,0,1,0,0,0,0,0,0),
- array(1,1,0,0,0,0,0,0,0),
- array(1,0,1,0,0,0,0,0,0),
- array(1,0,0,1,0,0,0,0,0),
- array(1,0,0,0,1,0,0,0,0),
- array(1,0,0,0,0,1,0,0,0),
- array(1,0,0,0,0,0,1,0,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- ),
- 'L' => array(
- array(0,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,1,1,1,1,1,1,1,1),
- ),
- 'M' => array(
- array(1,1,0,0,0,0,0,1,1),
- array(1,1,0,0,0,0,0,1,1),
- array(1,0,1,0,0,0,1,0,1),
- array(1,0,1,0,0,0,1,0,1),
- array(1,0,1,0,0,0,1,0,1),
- array(1,0,0,1,0,1,0,0,1),
- array(1,0,0,1,0,1,0,0,1),
- array(1,0,0,1,0,1,0,0,1),
- array(1,0,0,0,1,0,0,0,1),
- array(1,0,0,0,1,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- ),
- 'N' => array(
- array(1,1,0,0,0,0,0,0,1),
- array(1,1,0,0,0,0,0,0,1),
- array(1,0,1,0,0,0,0,0,1),
- array(1,0,1,0,0,0,0,0,1),
- array(1,0,0,1,0,0,0,0,1),
- array(1,0,0,1,0,0,0,0,1),
- array(1,0,0,0,1,0,0,0,1),
- array(1,0,0,0,1,0,0,0,1),
- array(1,0,0,0,1,0,0,0,1),
- array(1,0,0,0,0,1,0,0,1),
- array(1,0,0,0,0,1,0,0,1),
- array(1,0,0,0,0,0,1,0,1),
- array(1,0,0,0,0,0,1,0,1),
- array(1,0,0,0,0,0,0,1,1),
- array(1,0,0,0,0,0,0,1,1),
- ),
- 'O' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- 'P' => array(
- array(1,1,1,1,1,1,1,0,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,1,0),
- array(1,1,1,1,1,1,1,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- ),
- 'Q' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,1,0,0,1),
- array(1,0,0,0,0,0,1,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,1),
- ),
- 'R' => array(
- array(1,1,1,1,1,1,1,0,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,1,0),
- array(1,1,1,1,1,1,1,0,0),
- array(1,1,1,0,0,0,0,0,0),
- array(1,0,0,1,0,0,0,0,0),
- array(1,0,0,0,1,0,0,0,0),
- array(1,0,0,0,0,1,0,0,0),
- array(1,0,0,0,0,0,1,0,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- ),
- 'S' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(0,1,0,0,0,0,0,0,0),
- array(0,0,1,1,1,1,1,0,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- 'T' => array(
- array(1,1,1,1,1,1,1,1,1),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- ),
- 'U' => array(
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- 'V' => array(
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,1,0,0,0,0,0,1,0),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- ),
- 'W' => array( // New 'W', supplied by MHobbit
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,1,0,0,0,1),
- array(1,0,0,0,1,0,0,0,1),
- array(1,0,0,1,0,1,0,0,1),
- array(1,0,0,1,0,1,0,0,1),
- array(1,0,0,1,0,1,0,0,1),
- array(1,0,1,0,0,0,1,0,1),
- array(1,0,1,0,0,0,1,0,1),
- array(1,0,1,0,0,0,1,0,1),
- array(1,1,0,0,0,0,0,1,1),
- array(1,1,0,0,0,0,0,1,1),
- ),
- 'X' => array(
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,1,0,0,0,0,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- ),
- 'Y' => array(
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,0,0,1,0,1,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- ),
- 'Z' => array( // New 'Z' supplied by Anon
- array(1,1,1,1,1,1,1,1,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,1,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,1,0,0,0,0,0),
- array(0,0,0,1,0,0,0,0,0),
- array(0,0,1,0,0,0,0,0,0),
- array(0,1,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,1,1,1,1,1,1,1,1),
- ),
- '1' => array(
- array(0,0,0,1,1,0,0,0,0),
- array(0,0,1,0,1,0,0,0,0),
- array(0,1,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,1,1,1,1,1,1,1,0),
- ),
- '2' => array( // New '2' supplied by Anon
- array(0,0,0,1,1,1,0,0,0),
- array(0,0,1,0,0,0,1,0,0),
- array(0,1,0,0,0,0,1,1,0),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,1,1),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,1,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,1,0,0,0,0,0),
- array(0,0,1,0,0,0,0,0,0),
- array(0,1,0,0,0,0,0,0,0),
- array(1,1,1,1,1,1,1,1,1),
- array(0,0,0,0,0,0,0,0,0),
- ),
- '3' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,1,1,0,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- '4' => array(
- array(0,0,0,0,0,0,1,1,0),
- array(0,0,0,0,0,1,0,1,0),
- array(0,0,0,0,1,0,0,1,0),
- array(0,0,0,1,0,0,0,1,0),
- array(0,0,1,0,0,0,0,1,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,1,0),
- array(1,1,1,1,1,1,1,1,1),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,1,0),
- ),
- '5' => array(
- array(1,1,1,1,1,1,1,1,1),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(0,1,0,0,0,0,0,0,0),
- array(0,0,1,1,1,1,1,0,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- '6' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,1,1,1,1,0,0),
- array(1,0,1,0,0,0,0,1,0),
- array(1,1,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- '7' => array(
- array(1,1,1,1,1,1,1,1,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,0,1,0),
- array(0,0,0,0,0,0,1,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,0,1,0,0,0),
- array(0,0,0,0,1,0,0,0,0),
- array(0,0,0,1,0,0,0,0,0),
- array(0,0,0,1,0,0,0,0,0),
- array(0,0,1,0,0,0,0,0,0),
- array(0,1,0,0,0,0,0,0,0),
- array(0,1,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- array(1,0,0,0,0,0,0,0,0),
- ),
- '8' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- '9' => array(
- array(0,0,1,1,1,1,1,0,0),
- array(0,1,0,0,0,0,0,1,0),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,1,1),
- array(0,1,0,0,0,0,1,0,1),
- array(0,0,1,1,1,1,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(0,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(1,0,0,0,0,0,0,0,1),
- array(0,1,0,0,0,0,0,1,0),
- array(0,0,1,1,1,1,1,0,0),
- ),
- )
- );
-}
-
-
-/**
-* Load True Type Fonts
-*/
-function captcha_load_ttf_fonts()
-{
- static $load_files = array();
-
- if (sizeof($load_files) > 0)
- {
- return $load_files;
+ // Output image
+ header('Content-Type: image/png');
+ header('Cache-control: no-cache, no-store');
+ imagepng($image);
+ imagedestroy($image);
}
- global $phpbb_root_path;
-
- $dr = opendir($phpbb_root_path . 'includes/captcha/fonts');
- while (false !== ($entry = readdir($dr)))
+ function get_font()
{
- if (strtolower(pathinfo($entry, PATHINFO_EXTENSION)) == 'ttf')
- {
- $load_files[$entry] = $phpbb_root_path . 'includes/captcha/fonts/' . $entry;
- }
- }
- closedir($dr);
-
- return $load_files;
-}
-
-
-/**
-* Return vectors
-*/
-function captcha_vectors()
-{
- return array(
- 'A' => array(
- array('line', 0.00, 0.00, 0.50, 1.00, 1.10714871779, 1.11803398875),
- array('line', 1.00, 0.00, 0.50, 1.00, 2.0344439358, 1.11803398875),
- array('line', 0.25, 0.50, 0.75, 0.50, 0.00, 0.50),
- ),
- 'B' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 1.00, 0.70, 1.00, 0.00, 0.70),
- array('line', 0.00, 0.50, 0.70, 0.50, 0.00, 0.70),
- array('line', 0.00, 0.00, 0.70, 0.00, 0.00, 0.70),
- array('arc', 0.70, 0.75, 0.60, 0.50, 270, 90),
- array('arc', 0.70, 0.25, 0.60, 0.50, 270, 90),
- ),
- 'C' => array(
- array('arc', 0.50, 0.50, 1.00, 1.00, 45, 315),
- ),
- 'D' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 0.00, 0.50, 0.00, 0.00, 0.50),
- array('line', 0.00, 1.00, 0.50, 1.00, 0.00, 0.50),
- array('arc', 0.50, 0.50, 1.00, 1.00, 270, 90),
- ),
- 'E' => array(
- array('line', 0.00, 0.00, 1.00, 0.00, 0.00, 1.00),
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 1.00, 1.00, 1.00, 0.00, 1.00),
- array('line', 0.00, 0.50, 0.50, 0.50, 0.00, 0.50),
- ),
- 'F' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 1.00, 1.00, 1.00, 0.00, 1.00),
- array('line', 0.00, 0.50, 0.50, 0.50, 0.00, 0.50),
- ),
- 'G' => array(
- array('line', 0.50, 0.50, 1.00, 0.50, 0.00, 0.50),
- array('line', 1.00, 0.00, 1.00, 0.50, 1.57079632679, 0.50),
- array('arc', 0.50, 0.50, 1.00, 1.00, 0, 315),
- ),
- 'H' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 1.00, 0.00, 1.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 0.50, 1.00, 0.50, 0.00, 1.00),
- ),
- 'I' => array(
- array('line', 0.00, 0.00, 1.00, 0.00, 0.00, 1.00),
- array('line', 0.00, 1.00, 1.00, 1.00, 0.00, 1.00),
- array('line', 0.50, 0.00, 0.50, 1.00, 1.57079632679, 1.00),
- ),
- 'J' => array(
- array('line', 1.00, 1.00, 1.00, 0.25, -1.57079632679, 0.75),
- array('arc', 0.50, 0.25, 1.00, 0.50, 0, 180),
- ),
- 'K' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 0.50, 1.00, 1.00, 0.463647609001, 1.11803398875),
- array('line', 0.00, 0.50, 1.00, 0.00, -0.463647609001, 1.11803398875),
- ),
- 'L' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 0.00, 1.00, 0.00, 0.00, 1.00),
- ),
- 'M' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.50, 0.50, 0.00, 1.00, 2.35619449019, 0.707106781187),
- array('line', 0.50, 0.50, 1.00, 1.00, 0.785398163397, 0.707106781187),
- array('line', 1.00, 0.00, 1.00, 1.00, 1.57079632679, 1.00),
- ),
- 'N' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 1.00, 1.00, 0.00, -0.785398163397, 1.41421356237),
- array('line', 1.00, 0.00, 1.00, 1.00, 1.57079632679, 1.00),
- ),
- 'O' => array(
- array('arc', 0.50, 0.50, 1.00, 1.00, 0, 360),
- ),
- 'P' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 1.00, 0.70, 1.00, 0.00, 0.70),
- array('line', 0.00, 0.50, 0.70, 0.50, 0.00, 0.70),
- array('arc', 0.70, 0.75, 0.60, 0.50, 270, 90),
- ),
- 'Q' => array(
- array('line', 0.70, 0.30, 1.00, 0.00, -0.785398163397, 0.424264068712),
- array('arc', 0.50, 0.50, 1.00, 1.00, 0, 360),
- ),
- 'R' => array(
- array('line', 0.00, 0.00, 0.00, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 1.00, 0.70, 1.00, 0.00, 0.70),
- array('line', 0.00, 0.50, 0.70, 0.50, 0.00, 0.70),
- array('line', 0.50, 0.50, 1.00, 0.00, -0.785398163397, 0.707106781187),
- array('arc', 0.70, 0.75, 0.60, 0.50, 270, 90),
- ),
- 'S' => array(
- array('arc', 0.50, 0.75, 1.00, 0.50, 90, 360),
- array('arc', 0.50, 0.25, 1.00, 0.50, 270, 180),
- ),
- 'T' => array(
- array('line', 0.00, 1.00, 1.00, 1.00, 0.00, 1.00),
- array('line', 0.50, 0.00, 0.50, 1.00, 1.57079632679, 1.00),
- ),
- 'U' => array(
- array('line', 0.00, 1.00, 0.00, 0.25, -1.57079632679, 0.75),
- array('line', 1.00, 1.00, 1.00, 0.25, -1.57079632679, 0.75),
- array('arc', 0.50, 0.25, 1.00, 0.50, 0, 180),
- ),
- 'V' => array(
- array('line', 0.00, 1.00, 0.50, 0.00, -1.10714871779, 1.11803398875),
- array('line', 1.00, 1.00, 0.50, 0.00, -2.0344439358, 1.11803398875),
- ),
- 'W' => array(
- array('line', 0.00, 1.00, 0.25, 0.00, -1.32581766367, 1.0307764064),
- array('line', 0.50, 0.50, 0.25, 0.00, -2.0344439358, 0.559016994375),
- array('line', 0.50, 0.50, 0.75, 0.00, -1.10714871779, 0.559016994375),
- array('line', 1.00, 1.00, 0.75, 0.00, -1.81577498992, 1.0307764064),
- ),
- 'X' => array(
- array('line', 0.00, 1.00, 1.00, 0.00, -0.785398163397, 1.41421356237),
- array('line', 0.00, 0.00, 1.00, 1.00, 0.785398163397, 1.41421356237),
- ),
- 'Y' => array(
- array('line', 0.00, 1.00, 0.50, 0.50, -0.785398163397, 0.707106781187),
- array('line', 1.00, 1.00, 0.50, 0.50, -2.35619449019, 0.707106781187),
- array('line', 0.50, 0.50, 0.50, 0.00, -1.57079632679, 0.50),
- ),
- 'Z' => array(
- array('line', 0.00, 1.00, 1.00, 1.00, 0.00, 1.00),
- array('line', 0.00, 0.00, 1.00, 1.00, 0.785398163397, 1.41421356237),
- array('line', 0.00, 0.00, 1.00, 0.00, 0.00, 1.00),
- ),
- '1' => array(
- array('line', 0.00, 0.75, 0.50, 1.00, 0.463647609001, 0.559016994375),
- array('line', 0.50, 0.00, 0.50, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 0.00, 1.00, 0.00, 0.00, 1.00),
- ),
- '2' => array(
- array('line', 0.00, 0.00, 1.00, 0.00, 0.00, 1.00),
- array('arc', 0.50, 0.70, 1.00, 0.60, 180, 360),
- array('arc', 0.50, 0.70, 1.00, 0.70, 0, 90),
- array('arc', 0.50, 0.00, 1.00, 0.70, 180, 270),
- ),
- '3' => array(
- array('arc', 0.50, 0.75, 1.00, 0.50, 180, 90),
- array('arc', 0.50, 0.25, 1.00, 0.50, 270, 180),
- ),
- '4' => array(
- array('line', 0.70, 0.00, 0.70, 1.00, 1.57079632679, 1.00),
- array('line', 0.00, 0.50, 0.70, 1.00, 0.620249485983, 0.860232526704),
- array('line', 0.00, 0.50, 1.00, 0.50, 0.00, 1.00),
- ),
- '5' => array(
- array('line', 0.00, 1.00, 1.00, 1.00, 0.00, 1.00),
- array('line', 0.00, 1.00, 0.00, 0.60, -1.57079632679, 0.4),
- array('line', 0.00, 0.60, 0.50, 0.60, 0.00, 0.50),
- array('arc', 0.50, 0.30, 1.00, 0.60, 270, 180),
- ),
- '6' => array(
- array('arc', 0.50, 0.50, 1.00, 1.00, 90, 315),
- array('arc', 0.50, 0.30, 0.80, 0.60, 0, 360),
- ),
- '7' => array(
- array('line', 0.00, 1.00, 1.00, 1.00, 0.00, 1.00),
- array('line', 0.50, 0.00, 1.00, 1.00, 1.10714871779, 1.11803398875),
- ),
- '8' => array(
- array('arc', 0.50, 0.75, 1.00, 0.50, 0, 360),
- array('arc', 0.50, 0.25, 1.00, 0.50, 0, 360),
- ),
- '9' => array(
- array('arc', 0.50, 0.50, 1.00, 1.00, 270, 135),
- array('arc', 0.50, 0.70, 0.80, 0.60, 0, 360),
- )
- );
-}
-
-/**
-* @package VC
-*/
-class color_manager
-{
- var $img;
- var $mode;
- var $colors;
- var $named_colors;
- var $named_rgb = array(
- 'red' => array(0xff, 0x00, 0x00),
- 'maroon' => array(0x80, 0x00, 0x00),
- 'yellow' => array(0xff, 0xff, 0x00),
- 'olive' => array(0x80, 0x80, 0x00),
- 'lime' => array(0x00, 0xff, 0x00),
- 'green' => array(0x00, 0x80, 0x00),
- 'aqua' => array(0x00, 0xff, 0xff),
- 'teal' => array(0x00, 0x80, 0x80),
- 'blue' => array(0x00, 0x00, 0xff),
- 'navy' => array(0x00, 0x00, 0x80),
- 'fuchsia' => array(0xff, 0x00, 0xff),
- 'purple' => array(0x80, 0x00, 0x80),
- 'white' => array(0xff, 0xff, 0xff),
- 'silver' => array(0xc0, 0xc0, 0xc0),
- 'gray' => array(0x80, 0x80, 0x80),
- 'black' => array(0x00, 0x00, 0x00),
- );
-
- /**
- * Create the color manager, link it to
- * the image resource
- */
- function color_manager($img, $background = false, $mode = 'ahsv')
- {
- $this->img = $img;
- $this->mode = $mode;
- $this->colors = array();
- $this->named_colors = array();
- if ($background !== false)
- {
- $bg = $this->allocate_named('background', $background);
- imagefill($this->img, 0, 0, $bg);
- }
- }
-
- /**
- * Lookup a named color resource
- */
- function r($named_color)
- {
- if (isset($this->named_colors[$named_color]))
- {
- return $this->named_colors[$named_color];
- }
- if (isset($this->named_rgb[$named_color]))
- {
- return $this->allocate_named($named_color, $this->named_rgb[$named_color], 'rgb');
- }
- return false;
- }
-
- /**
- * Assign a name to a color resource
- */
- function name_color($name, $resource)
- {
- $this->named_colors[$name] = $resource;
- }
-
- /**
- * random color resource
- */
- function r_rand($colors)
- {
- return $colors[array_rand($colors)];
- }
-
- /**
- * names and allocates a color resource
- */
- function allocate_named($name, $color, $mode = false)
- {
- $resource = $this->allocate($color, $mode);
- if ($resource !== false)
- {
- $this->name_color($name, $resource);
- }
- return $resource;
- }
-
- /**
- * allocates a specified color into the image
- */
- function allocate($color, $mode = false)
- {
- if ($mode === false)
- {
- $mode = $this->mode;
- }
- if (!is_array($color))
- {
- if (isset($this->named_rgb[$color]))
- {
- return $this->allocate_named($color, $this->named_rgb[$color], 'rgb');
- }
- if (!is_int($color))
- {
- return false;
- }
- $mode = 'rgb';
- $color = array(
- 255 & ($color >> 16),
- 255 & ($color >> 8),
- 255 & $color,
- );
- }
-
- if (isset($color['mode']))
- {
- $mode = $color['mode'];
- unset($color['mode']);
- }
- if (isset($color['random']))
- {
- unset($color['random']);
- // everything else is params
- return $this->random_color($color, $mode);
- }
-
- $rgb = color_manager::model_convert($color, $mode, 'rgb');
- $store = ($this->mode == 'rgb') ? $rgb : color_manager::model_convert($color, $mode, $this->mode);
- $resource = imagecolorallocate($this->img, $rgb[0], $rgb[1], $rgb[2]);
-
- $this->colors[$resource] = $store;
-
- return $resource;
- }
-
- /**
- * randomly generates a color, with optional params
- */
- function random_color($params = array(), $mode = false)
- {
- if ($mode === false)
- {
- $mode = $this->mode;
- }
- switch ($mode)
- {
- case 'rgb':
-
- // @TODO random rgb generation. do we intend to do this, or is it just too tedious?
-
- break;
-
- case 'ahsv':
- case 'hsv':
- default:
-
- $default_params = array(
- 'hue_bias' => false, // degree / 'r'/'g'/'b'/'c'/'m'/'y' /'o'
- 'hue_range' => false, // if hue bias, then difference range +/- from bias
- 'min_saturation' => 30, // 0 - 100
- 'max_saturation' => 100, // 0 - 100
- 'min_value' => 30, // 0 - 100
- 'max_value' => 100, // 0 - 100
- );
-
- $alt = ($mode == 'ahsv');
-
- $params = array_merge($default_params, $params);
-
- $min_hue = 0;
- $max_hue = 359;
- $min_saturation = max(0, $params['min_saturation']);
- $max_saturation = min(100, $params['max_saturation']);
- $min_value = max(0, $params['min_value']);
- $max_value = min(100, $params['max_value']);
-
- if ($params['hue_bias'] !== false)
- {
- if (is_numeric($params['hue_bias']))
- {
- $h = intval($params['hue_bias']) % 360;
- }
- else
- {
- switch ($params['hue_bias'])
- {
- case 'o':
- $h = $alt ? 60 : 30;
- break;
-
- case 'y':
- $h = $alt ? 120 : 60;
- break;
-
- case 'g':
- $h = $alt ? 180 : 120;
- break;
-
- case 'c':
- $h = $alt ? 210 : 180;
- break;
-
- case 'b':
- $h = 240;
- break;
-
- case 'm':
- $h = 300;
- break;
-
- case 'r':
- default:
- $h = 0;
- break;
- }
- }
-
- $min_hue = $h + 360;
- $max_hue = $h + 360;
-
- if ($params['hue_range'])
- {
- $min_hue -= min(180, $params['hue_range']);
- $max_hue += min(180, $params['hue_range']);
- }
- }
-
- $h = mt_rand($min_hue, $max_hue);
- $s = mt_rand($min_saturation, $max_saturation);
- $v = mt_rand($min_value, $max_value);
-
- return $this->allocate(array($h, $s, $v), $mode);
-
- break;
- }
- }
+ static $fonts = array();
- function color_scheme($resource, $scheme, $include_original = true)
- {
- $mode = (in_array($this->mode, array('hsv', 'ahsv'), true) ? $this->mode : 'hsv');
- if (($pre = $this->r($resource)) !== false)
- {
- $resource = $pre;
- }
- $color = color_manager::model_convert($this->colors[$resource], $this->mode, $mode);
- $results = $include_original ? array($resource) : array();
-
- switch ($scheme)
+ if (!sizeof($fonts))
{
- case 'complement':
-
- $color2 = $color;
- $color2[0] += 180;
- $results[] = $this->allocate($color2, $mode);
-
- break;
-
- case 'triadic':
-
- $color2 = $color3 = $color;
- $color2[0] += 120;
- $color3[0] += 240;
- $results[] = $this->allocate($color2, $mode);
- $results[] = $this->allocate($color3, $mode);
-
- break;
-
- case 'tetradic':
-
- $color2 = $color3 = $color4 = $color;
- $color2[0] += 30;
- $color3[0] += 180;
- $color4[0] += 210;
- $results[] = $this->allocate($color2, $mode);
- $results[] = $this->allocate($color3, $mode);
- $results[] = $this->allocate($color4, $mode);
-
- break;
-
- case 'analogous':
-
- $color2 = $color3 = $color;
- $color2[0] += 30;
- $color3[0] += 330;
- $results[] = $this->allocate($color2, $mode);
- $results[] = $this->allocate($color3, $mode);
-
- break;
- }
- return $results;
- }
+ global $phpbb_root_path;
- function mono_range($resource, $type = 'both', $count = 5, $include_original = true)
- {
- if (is_array($resource))
- {
- $results = array();
- for ($i = 0, $size = sizeof($resource); $i < $size; ++$i)
+ $dr = opendir($phpbb_root_path . 'includes/captcha/fonts');
+ while (false !== ($entry = readdir($dr)))
{
- $results = array_merge($results, $this->mono_range($resource[$i], $type, $count, $include_original));
- }
- return $results;
- }
- $mode = (in_array($this->mode, array('hsv', 'ahsv'), true) ? $this->mode : 'ahsv');
- if (($pre = $this->r($resource)) !== false)
- {
- $resource = $pre;
- }
- $color = color_manager::model_convert($this->colors[$resource], $this->mode, $mode);
-
- $results = array();
- if ($include_original)
- {
- $results[] = $resource;
- $count--;
- }
-
- switch ($type)
- {
- case 'saturation':
-
- $pivot = $color[1];
- $num_below = intval(($pivot * $count) / 100);
- $num_above = $count - $num_below;
-
- for ($i = $num_above; $i > 0; --$i)
- {
- $color[1] = (($i * 100) + (($num_above - $i) * $pivot)) / $num_above;
- $results[] = $this->allocate($color, $mode);
- }
-
- ++$num_below;
-
- for ($i = $num_below - 1; $i > 0; --$i)
- {
- $color[1] = ($i * $pivot) / $num_below;;
- $results[] = $this->allocate($color, $mode);
- }
-
- return $results;
-
- break;
-
- case 'value':
-
- $pivot = $color[2];
- $num_below = intval(($pivot * $count) / 100);
- $num_above = $count - $num_below;
-
- for ($i = $num_above; $i > 0; --$i)
- {
- $color[2] = (($i * 100) + (($num_above - $i) * $pivot)) / $num_above;
- $results[] = $this->allocate($color, $mode);
- }
-
- ++$num_below;
-
- for ($i = $num_below - 1; $i > 0; --$i)
- {
- $color[2] = ($i * $pivot) / $num_below;;
- $results[] = $this->allocate($color, $mode);
- }
-
- return $results;
-
- break;
-
- case 'both':
-
- // This is a hard problem. I chicken out and do an even triangle
- // the problem is that it disregards the original saturation and value,
- // and as such a generated result might come arbitrarily close to our original value.
- $length = ceil(sqrt($count * 2));
- for ($i = $length; $i > 0; --$i)
- {
- for ($j = $i; $j > 0; --$j)
- {
- $color[1] = ($i * 100) / $length;
- $color[2] = ($j * 100) / $i;
- $results[] = $this->allocate($color, $mode);
- --$count;
- if (!$count)
- {
- return $results;
- }
- }
- }
-
- return $results;
-
- break;
- }
-
- return false;
- }
-
- function is_dark($resource)
- {
- $color = (($pre = $this->r($resource)) !== false) ? $this->colors[$pre] : $this->colors[$resource];
- switch($this->mode)
- {
- case 'ahsv':
- case 'hsv':
-
- return ($color[2] <= 50);
-
- break;
-
- case 'rgb':
-
- return (max($color[0], $color[1], $color[2]) <= 128);
-
- break;
- }
- return false;
- }
-
- /**
- * Convert from one color model to another
- *
- * note: properly following coding standards here yields unweildly amounts of whitespace, rendering this less than easily readable
- *
- */
- function model_convert($color, $from_model, $to_model)
- {
- if ($from_model == $to_model)
- {
- return $color;
- }
- switch ($to_model)
- {
- case 'hsv':
- switch($from_model)
- {
- case 'ahsv':
- return color_manager::ah2h($color);
- break;
-
- case 'rgb':
- return color_manager::rgb2hsv($color);
- break;
- }
- break;
-
- case 'ahsv':
- switch($from_model)
- {
- case 'hsv':
- return color_manager::h2ah($color);
- break;
-
- case 'rgb':
- return color_manager::h2ah(color_manager::rgb2hsv($color));
- break;
- }
- break;
-
- case 'rgb':
- switch($from_model)
+ if (strtolower(pathinfo($entry, PATHINFO_EXTENSION)) == 'ttf')
{
- case 'hsv':
- return color_manager::hsv2rgb($color);
- break;
-
- case 'ahsv':
- return color_manager::hsv2rgb(color_manager::ah2h($color));
- break;
+ $fonts[] = $phpbb_root_path . 'includes/captcha/fonts/' . $entry;
}
- break;
- }
- return false;
- }
-
- /**
- * Slightly altered from wikipedia's algorithm
- */
- function hsv2rgb($hsv)
- {
- color_manager::normalize_hue($hsv[0]);
- $h = $hsv[0];
- $s = min(1, max(0, $hsv[1] / 100));
- $v = min(1, max(0, $hsv[2] / 100));
-
- $hi = floor($hsv[0] / 60); // calculate hue sector
-
- $p = $v * (1 - $s); // calculate opposite color
- $f = ($h / 60) - $hi; // calculate distance between hex vertices
- if (!($hi & 1)) // coming in or going out?
- {
- $f = 1 - $f;
- }
- $q = $v * (1 - ($f * $s)); // calculate adjacent color
-
- switch ($hi)
- {
- case 0:
- $rgb = array($v, $q, $p);
- break;
-
- case 1:
- $rgb = array($q, $v, $p);
- break;
-
- case 2:
- $rgb = array($p, $v, $q);
- break;
-
- case 3:
- $rgb = array($p, $q, $v);
- break;
-
- case 4:
- $rgb = array($q, $p, $v);
- break;
-
- case 5:
- $rgb = array($v, $p, $q);
- break;
-
- default:
- return array(0, 0, 0);
- break;
- }
- return array(255 * $rgb[0], 255 * $rgb[1], 255 * $rgb[2]);
- }
-
- /**
- * (more than) Slightly altered from wikipedia's algorithm
- */
- function rgb2hsv($rgb)
- {
- $r = min(255, max(0, $rgb[0]));
- $g = min(255, max(0, $rgb[1]));
- $b = min(255, max(0, $rgb[2]));
- $max = max($r, $g, $b);
- $min = min($r, $g, $b);
-
- $v = $max / 255;
- $s = (!$max) ? 0 : 1 - ($min / $max);
- $h = $max - $min; // if max - min is 0, we want hue to be 0 anyway.
- if ($h)
- {
- switch ($max)
- {
- case $g:
- $h = 120 + (60 * ($b - $r) / $h);
- break;
-
- case $b:
- $h = 240 + (60 * ($r - $g) / $h);
- break;
-
- case $r:
- $h = 360 + (60 * ($g - $b) / $h);
- break;
}
+ closedir($dr);
}
- color_manager::normalize_hue($h);
- return array($h, $s * 100, $v * 100);
- }
-
- /**
- * Bleh
- */
- function normalize_hue(&$hue)
- {
- $hue %= 360;
- if ($hue < 0)
- {
- $hue += 360;
- }
- }
-
- /**
- * Alternate hue to hue
- */
- function ah2h($ahue)
- {
- if (is_array($ahue))
- {
- $ahue[0] = color_manager::ah2h($ahue[0]);
- return $ahue;
- }
- color_manager::normalize_hue($ahue);
- if ($ahue >= 240) // blue through red is already ok
- {
- return $ahue;
- }
- if ($ahue >= 180) // ahue green is at 180
- {
- // return (240 - (2 * (240 - $ahue)));
- return (2 * $ahue) - 240; // equivalent
- }
- if ($ahue >= 120) // ahue yellow is at 120 (RYB rather than RGB)
- {
- return $ahue - 60;
- }
- return $ahue / 2;
- }
- /**
- * hue to Alternate hue
- */
- function h2ah($hue)
- {
- if (is_array($hue))
- {
- $hue[0] = color_manager::h2ah($hue[0]);
- return $hue;
- }
- color_manager::normalize_hue($hue);
- if ($hue >= 240) // blue through red is already ok
- {
- return $hue;
- }
- else if ($hue <= 60)
- {
- return $hue * 2;
- }
- else if ($hue <= 120)
- {
- return $hue + 60;
- }
- else
- {
- return ($hue + 240) / 2;
- }
- }
-}
-
-function vector_distance(&$char, $x, $y, $range = 0.1)
-{
- $distance = $range + 1;
- foreach ($char AS $vector)
- {
- $d = $range + 1;
- switch ($vector[0])
- {
- case 'arc':
-
- $dx = $x - $vector[1];
- $dy = -($y - $vector[2]); //because our arcs are upside-down....
- if (abs($dx) > abs($dy))
- {
- $phi = rad2deg(atan(($dy * $vector[3])/($dx * $vector[4])));
- $phi += ($dx < 0) ? 180 : 360;
- $phi %= 360;
- }
- else
- {
- $phi = 90 - rad2deg(atan(($dx * $vector[4])/($dy * $vector[3])));
- $phi += ($dy < 0) ? 180 : 360;
- $phi %= 360;
- }
-
- $internal = $vector[6] > $vector[5]; //external wraps over the 360 point
- $low = $phi >= $vector[5]; //phi is above our low range
- $high = $phi <= $vector[6]; //phi is below our high range.
- if ($internal ? ($low && $high) : ($low || $high)) //if it wraps, it can only be one or the other
- {
- $radphi = deg2rad($phi); // i'm awesome. or not.
- $px = cos($radphi) * 0.5 * $vector[3];
- $py = sin($radphi) * 0.5 * $vector[4];
- $d = sqrt(pow($px - $dx, 2) + pow($py - $dy, 2));
- }
-
- break;
-
- case 'line':
-
- $bx = $x - $vector[1];
- $by = $y - $vector[2];
- $dx = cos($vector[5]);
- $dy = sin($vector[5]);
- $r = ($by * $dx) - ($bx * $dy);
- if ($r < $range && $r > -$range)
- {
- if (abs($dx) > abs($dy))
- {
- $s = (($bx + ($dy * $r)) / $dx);
- }
- else
- {
- $s = (($by + ($dx * $r)) / $dy);
- }
- if ($s > -$range)
- {
- if ($s < 0)
- {
- $d = sqrt(pow($s, 2) + pow($r, 2));
- }
- elseif ($s < $vector[6])
- {
- $d = $r;
- }
- elseif ($s < $vector[6] + $range)
- {
- $d = sqrt(pow($s - $vector[6], 2) + pow($r, 2));
- }
- }
- }
-
- break;
- }
- $distance = min($distance, abs($d));
+ return $fonts[array_rand($fonts)];
}
- return $distance;
}
?> \ No newline at end of file