5
* @version $Id: captcha_gd.php,v 1.23 2007/10/05 14:36:32 acydburn Exp $
6
* @copyright (c) 2006 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
14
if (!defined('IN_PHPBB'))
20
* Original Author - Xore (Robert Hetzler)
21
* With contributions from Neothermic
31
* Create the image containing $code with a seed of $seed
33
function execute($code, $seed)
40
$img = imagecreatetruecolor($this->width, $this->height);
43
$colour = new colour_manager($img, array(
48
$scheme = $colour->colour_scheme('background', false);
49
$scheme = $colour->mono_range($scheme, 10, false);
52
$bg_colours = array_splice($scheme, mt_rand(6, 12));
54
// Generate code characters
55
$characters = $sizes = $bounding_boxes = array();
56
$width_avail = $this->width - 15;
57
$code_len = strlen($code);
59
$captcha_bitmaps = $this->captcha_bitmaps();
60
for ($i = 0; $i < $code_len; ++$i)
62
$characters[$i] = new char_cube3d($captcha_bitmaps, $code[$i]);
64
list($min, $max) = $characters[$i]->range();
65
$sizes[$i] = mt_rand($min, $max);
67
$box = $characters[$i]->dimensions($sizes[$i]);
68
$width_avail -= ($box[2] - $box[0]);
69
$bounding_boxes[$i] = $box;
72
// Redistribute leftover x-space
74
for ($i = 0; $i < $code_len; ++$i)
76
$denom = ($code_len - $i);
77
$denom = max(1.3, $denom);
78
$offset[$i] = mt_rand(0, (1.5 * $width_avail) / $denom);
79
$width_avail -= $offset[$i];
82
if ($config['captcha_gd_x_grid'])
84
$grid = (int) $config['captcha_gd_x_grid'];
85
for ($y = 0; $y < $this->height; $y += mt_rand($grid - 2, $grid + 2))
87
$current_colour = $scheme[array_rand($scheme)];
88
imageline($img, mt_rand(0,4), mt_rand($y - 3, $y), mt_rand($this->width - 5, $this->width), mt_rand($y - 3, $y), $current_colour);
92
if ($config['captcha_gd_y_grid'])
94
$grid = (int) $config['captcha_gd_y_grid'];
95
for ($x = 0; $x < $this->width; $x += mt_rand($grid - 2, $grid + 2))
97
$current_colour = $scheme[array_rand($scheme)];
98
imagedashedline($img, mt_rand($x -3, $x + 3), mt_rand(0, 4), mt_rand($x -3, $x + 3), mt_rand($this->height - 5, $this->height), $current_colour);
103
for ($i = 0; $i < $code_len; ++$i)
105
$dimm = $bounding_boxes[$i];
106
$xoffset += ($offset[$i] - $dimm[0]);
107
$yoffset = mt_rand(-$dimm[1], $this->height - $dimm[3]);
109
$characters[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $colour->get_resource('background'), $scheme);
110
$xoffset += $dimm[2];
113
if ($config['captcha_gd_foreground_noise'])
115
$this->noise_line($img, 0, 0, $this->width, $this->height, $colour->get_resource('background'), $scheme, $bg_colours);
119
header('Content-Type: image/png');
120
header('Cache-control: no-cache, no-store');
128
function noise_line($img, $min_x, $min_y, $max_x, $max_y, $bg, $font, $non_font)
130
imagesetthickness($img, 2);
140
array_fill(0, mt_rand(30, 60), $non_font[array_rand($non_font)]),
141
array_fill(0, mt_rand(30, 60), $bg)
144
imagesetstyle($img, $line);
145
imageline($img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
147
$y1 += mt_rand(12, 35);
148
$y2 += mt_rand(12, 35);
150
while ($y1 < $max_y && $y2 < $max_y);
160
array_fill(0, mt_rand(30, 60), $non_font[array_rand($non_font)]),
161
array_fill(0, mt_rand(30, 60), $bg)
164
imagesetstyle($img, $line);
165
imageline($img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED);
167
$x1 += mt_rand(20, 35);
168
$x2 += mt_rand(20, 35);
170
while ($x1 < $max_x && $x2 < $max_x);
171
imagesetthickness($img, 1);
177
function captcha_bitmaps()
185
array(0,0,0,0,1,0,0,0,0),
186
array(0,0,0,1,0,1,0,0,0),
187
array(0,0,0,1,0,1,0,0,0),
188
array(0,0,0,1,0,1,0,0,0),
189
array(0,0,1,0,0,0,1,0,0),
190
array(0,0,1,0,0,0,1,0,0),
191
array(0,0,1,0,0,0,1,0,0),
192
array(0,1,0,0,0,0,0,1,0),
193
array(0,1,0,0,0,0,0,1,0),
194
array(0,1,1,1,1,1,1,1,0),
195
array(0,1,0,0,0,0,0,1,0),
196
array(1,0,0,0,0,0,0,0,1),
197
array(1,0,0,0,0,0,0,0,1),
198
array(1,0,0,0,0,0,0,0,1),
199
array(1,0,0,0,0,0,0,0,1),
202
array(1,1,1,1,1,1,1,0,0),
203
array(1,0,0,0,0,0,0,1,0),
204
array(1,0,0,0,0,0,0,0,1),
205
array(1,0,0,0,0,0,0,0,1),
206
array(1,0,0,0,0,0,0,0,1),
207
array(1,0,0,0,0,0,0,0,1),
208
array(1,0,0,0,0,0,0,1,0),
209
array(1,1,1,1,1,1,1,0,0),
210
array(1,0,0,0,0,0,0,1,0),
211
array(1,0,0,0,0,0,0,0,1),
212
array(1,0,0,0,0,0,0,0,1),
213
array(1,0,0,0,0,0,0,0,1),
214
array(1,0,0,0,0,0,0,0,1),
215
array(1,0,0,0,0,0,0,1,0),
216
array(1,1,1,1,1,1,1,0,0),
219
array(0,0,1,1,1,1,1,0,0),
220
array(0,1,0,0,0,0,0,1,0),
221
array(1,0,0,0,0,0,0,0,1),
222
array(1,0,0,0,0,0,0,0,1),
223
array(1,0,0,0,0,0,0,0,0),
224
array(1,0,0,0,0,0,0,0,0),
225
array(1,0,0,0,0,0,0,0,0),
226
array(1,0,0,0,0,0,0,0,0),
227
array(1,0,0,0,0,0,0,0,0),
228
array(1,0,0,0,0,0,0,0,0),
229
array(1,0,0,0,0,0,0,0,0),
230
array(1,0,0,0,0,0,0,0,1),
231
array(1,0,0,0,0,0,0,0,1),
232
array(0,1,0,0,0,0,0,1,0),
233
array(0,0,1,1,1,1,1,0,0),
236
array(1,1,1,1,1,1,1,0,0),
237
array(1,0,0,0,0,0,0,1,0),
238
array(1,0,0,0,0,0,0,0,1),
239
array(1,0,0,0,0,0,0,0,1),
240
array(1,0,0,0,0,0,0,0,1),
241
array(1,0,0,0,0,0,0,0,1),
242
array(1,0,0,0,0,0,0,0,1),
243
array(1,0,0,0,0,0,0,0,1),
244
array(1,0,0,0,0,0,0,0,1),
245
array(1,0,0,0,0,0,0,0,1),
246
array(1,0,0,0,0,0,0,0,1),
247
array(1,0,0,0,0,0,0,0,1),
248
array(1,0,0,0,0,0,0,0,1),
249
array(1,0,0,0,0,0,0,1,0),
250
array(1,1,1,1,1,1,1,0,0),
253
array(1,1,1,1,1,1,1,1,1),
254
array(1,0,0,0,0,0,0,0,0),
255
array(1,0,0,0,0,0,0,0,0),
256
array(1,0,0,0,0,0,0,0,0),
257
array(1,0,0,0,0,0,0,0,0),
258
array(1,0,0,0,0,0,0,0,0),
259
array(1,0,0,0,0,0,0,0,0),
260
array(1,1,1,1,1,1,1,1,0),
261
array(1,0,0,0,0,0,0,0,0),
262
array(1,0,0,0,0,0,0,0,0),
263
array(1,0,0,0,0,0,0,0,0),
264
array(1,0,0,0,0,0,0,0,0),
265
array(1,0,0,0,0,0,0,0,0),
266
array(1,0,0,0,0,0,0,0,0),
267
array(1,1,1,1,1,1,1,1,1),
270
array(1,1,1,1,1,1,1,1,1),
271
array(1,0,0,0,0,0,0,0,0),
272
array(1,0,0,0,0,0,0,0,0),
273
array(1,0,0,0,0,0,0,0,0),
274
array(1,0,0,0,0,0,0,0,0),
275
array(1,0,0,0,0,0,0,0,0),
276
array(1,0,0,0,0,0,0,0,0),
277
array(1,1,1,1,1,1,1,0,0),
278
array(1,0,0,0,0,0,0,0,0),
279
array(1,0,0,0,0,0,0,0,0),
280
array(1,0,0,0,0,0,0,0,0),
281
array(1,0,0,0,0,0,0,0,0),
282
array(1,0,0,0,0,0,0,0,0),
283
array(1,0,0,0,0,0,0,0,0),
284
array(1,0,0,0,0,0,0,0,0),
287
array(0,0,1,1,1,1,1,0,0),
288
array(0,1,0,0,0,0,0,1,0),
289
array(1,0,0,0,0,0,0,0,1),
290
array(1,0,0,0,0,0,0,0,0),
291
array(1,0,0,0,0,0,0,0,0),
292
array(1,0,0,0,0,0,0,0,0),
293
array(1,0,0,0,0,0,0,0,0),
294
array(1,0,0,0,0,0,0,0,0),
295
array(1,0,0,0,0,0,1,1,1),
296
array(1,0,0,0,0,0,0,0,1),
297
array(1,0,0,0,0,0,0,0,1),
298
array(1,0,0,0,0,0,0,0,1),
299
array(1,0,0,0,0,0,0,0,1),
300
array(0,1,0,0,0,0,0,1,0),
301
array(0,0,1,1,1,1,1,0,0),
304
array(1,0,0,0,0,0,0,0,1),
305
array(1,0,0,0,0,0,0,0,1),
306
array(1,0,0,0,0,0,0,0,1),
307
array(1,0,0,0,0,0,0,0,1),
308
array(1,0,0,0,0,0,0,0,1),
309
array(1,0,0,0,0,0,0,0,1),
310
array(1,0,0,0,0,0,0,0,1),
311
array(1,1,1,1,1,1,1,1,1),
312
array(1,0,0,0,0,0,0,0,1),
313
array(1,0,0,0,0,0,0,0,1),
314
array(1,0,0,0,0,0,0,0,1),
315
array(1,0,0,0,0,0,0,0,1),
316
array(1,0,0,0,0,0,0,0,1),
317
array(1,0,0,0,0,0,0,0,1),
318
array(1,0,0,0,0,0,0,0,1),
321
array(1,1,1,1,1,1,1,1,1),
322
array(0,0,0,0,1,0,0,0,0),
323
array(0,0,0,0,1,0,0,0,0),
324
array(0,0,0,0,1,0,0,0,0),
325
array(0,0,0,0,1,0,0,0,0),
326
array(0,0,0,0,1,0,0,0,0),
327
array(0,0,0,0,1,0,0,0,0),
328
array(0,0,0,0,1,0,0,0,0),
329
array(0,0,0,0,1,0,0,0,0),
330
array(0,0,0,0,1,0,0,0,0),
331
array(0,0,0,0,1,0,0,0,0),
332
array(0,0,0,0,1,0,0,0,0),
333
array(0,0,0,0,1,0,0,0,0),
334
array(0,0,0,0,1,0,0,0,0),
335
array(1,1,1,1,1,1,1,1,1),
338
array(1,1,1,1,1,1,1,1,1),
339
array(0,0,0,0,0,1,0,0,0),
340
array(0,0,0,0,0,1,0,0,0),
341
array(0,0,0,0,0,1,0,0,0),
342
array(0,0,0,0,0,1,0,0,0),
343
array(0,0,0,0,0,1,0,0,0),
344
array(0,0,0,0,0,1,0,0,0),
345
array(0,0,0,0,0,1,0,0,0),
346
array(0,0,0,0,0,1,0,0,0),
347
array(0,0,0,0,0,1,0,0,0),
348
array(0,0,0,0,0,1,0,0,0),
349
array(1,0,0,0,0,1,0,0,0),
350
array(1,0,0,0,0,1,0,0,0),
351
array(0,1,0,0,1,0,0,0,0),
352
array(0,0,1,1,0,0,0,0,0),
354
'K' => array( // New 'K', supplied by NeoThermic
355
array(1,0,0,0,0,0,0,0,1),
356
array(1,0,0,0,0,0,0,1,0),
357
array(1,0,0,0,0,0,1,0,0),
358
array(1,0,0,0,0,1,0,0,0),
359
array(1,0,0,0,1,0,0,0,0),
360
array(1,0,0,1,0,0,0,0,0),
361
array(1,0,1,0,0,0,0,0,0),
362
array(1,1,0,0,0,0,0,0,0),
363
array(1,0,1,0,0,0,0,0,0),
364
array(1,0,0,1,0,0,0,0,0),
365
array(1,0,0,0,1,0,0,0,0),
366
array(1,0,0,0,0,1,0,0,0),
367
array(1,0,0,0,0,0,1,0,0),
368
array(1,0,0,0,0,0,0,1,0),
369
array(1,0,0,0,0,0,0,0,1),
372
array(0,0,0,0,0,0,0,0,0),
373
array(1,0,0,0,0,0,0,0,0),
374
array(1,0,0,0,0,0,0,0,0),
375
array(1,0,0,0,0,0,0,0,0),
376
array(1,0,0,0,0,0,0,0,0),
377
array(1,0,0,0,0,0,0,0,0),
378
array(1,0,0,0,0,0,0,0,0),
379
array(1,0,0,0,0,0,0,0,0),
380
array(1,0,0,0,0,0,0,0,0),
381
array(1,0,0,0,0,0,0,0,0),
382
array(1,0,0,0,0,0,0,0,0),
383
array(1,0,0,0,0,0,0,0,0),
384
array(1,0,0,0,0,0,0,0,0),
385
array(1,0,0,0,0,0,0,0,0),
386
array(1,1,1,1,1,1,1,1,1),
389
array(1,1,0,0,0,0,0,1,1),
390
array(1,1,0,0,0,0,0,1,1),
391
array(1,0,1,0,0,0,1,0,1),
392
array(1,0,1,0,0,0,1,0,1),
393
array(1,0,1,0,0,0,1,0,1),
394
array(1,0,0,1,0,1,0,0,1),
395
array(1,0,0,1,0,1,0,0,1),
396
array(1,0,0,1,0,1,0,0,1),
397
array(1,0,0,0,1,0,0,0,1),
398
array(1,0,0,0,1,0,0,0,1),
399
array(1,0,0,0,0,0,0,0,1),
400
array(1,0,0,0,0,0,0,0,1),
401
array(1,0,0,0,0,0,0,0,1),
402
array(1,0,0,0,0,0,0,0,1),
403
array(1,0,0,0,0,0,0,0,1),
406
array(1,1,0,0,0,0,0,0,1),
407
array(1,1,0,0,0,0,0,0,1),
408
array(1,0,1,0,0,0,0,0,1),
409
array(1,0,1,0,0,0,0,0,1),
410
array(1,0,0,1,0,0,0,0,1),
411
array(1,0,0,1,0,0,0,0,1),
412
array(1,0,0,0,1,0,0,0,1),
413
array(1,0,0,0,1,0,0,0,1),
414
array(1,0,0,0,1,0,0,0,1),
415
array(1,0,0,0,0,1,0,0,1),
416
array(1,0,0,0,0,1,0,0,1),
417
array(1,0,0,0,0,0,1,0,1),
418
array(1,0,0,0,0,0,1,0,1),
419
array(1,0,0,0,0,0,0,1,1),
420
array(1,0,0,0,0,0,0,1,1),
423
array(0,0,1,1,1,1,1,0,0),
424
array(0,1,0,0,0,0,0,1,0),
425
array(1,0,0,0,0,0,0,0,1),
426
array(1,0,0,0,0,0,0,0,1),
427
array(1,0,0,0,0,0,0,0,1),
428
array(1,0,0,0,0,0,0,0,1),
429
array(1,0,0,0,0,0,0,0,1),
430
array(1,0,0,0,0,0,0,0,1),
431
array(1,0,0,0,0,0,0,0,1),
432
array(1,0,0,0,0,0,0,0,1),
433
array(1,0,0,0,0,0,0,0,1),
434
array(1,0,0,0,0,0,0,0,1),
435
array(1,0,0,0,0,0,0,0,1),
436
array(0,1,0,0,0,0,0,1,0),
437
array(0,0,1,1,1,1,1,0,0),
440
array(1,1,1,1,1,1,1,0,0),
441
array(1,0,0,0,0,0,0,1,0),
442
array(1,0,0,0,0,0,0,0,1),
443
array(1,0,0,0,0,0,0,0,1),
444
array(1,0,0,0,0,0,0,0,1),
445
array(1,0,0,0,0,0,0,0,1),
446
array(1,0,0,0,0,0,0,1,0),
447
array(1,1,1,1,1,1,1,0,0),
448
array(1,0,0,0,0,0,0,0,0),
449
array(1,0,0,0,0,0,0,0,0),
450
array(1,0,0,0,0,0,0,0,0),
451
array(1,0,0,0,0,0,0,0,0),
452
array(1,0,0,0,0,0,0,0,0),
453
array(1,0,0,0,0,0,0,0,0),
454
array(1,0,0,0,0,0,0,0,0),
457
array(0,0,1,1,1,1,1,0,0),
458
array(0,1,0,0,0,0,0,1,0),
459
array(1,0,0,0,0,0,0,0,1),
460
array(1,0,0,0,0,0,0,0,1),
461
array(1,0,0,0,0,0,0,0,1),
462
array(1,0,0,0,0,0,0,0,1),
463
array(1,0,0,0,0,0,0,0,1),
464
array(1,0,0,0,0,0,0,0,1),
465
array(1,0,0,0,0,0,0,0,1),
466
array(1,0,0,0,0,0,0,0,1),
467
array(1,0,0,0,0,0,0,0,1),
468
array(1,0,0,0,0,1,0,0,1),
469
array(1,0,0,0,0,0,1,0,1),
470
array(0,1,0,0,0,0,0,1,0),
471
array(0,0,1,1,1,1,1,0,1),
474
array(1,1,1,1,1,1,1,0,0),
475
array(1,0,0,0,0,0,0,1,0),
476
array(1,0,0,0,0,0,0,0,1),
477
array(1,0,0,0,0,0,0,0,1),
478
array(1,0,0,0,0,0,0,0,1),
479
array(1,0,0,0,0,0,0,0,1),
480
array(1,0,0,0,0,0,0,1,0),
481
array(1,1,1,1,1,1,1,0,0),
482
array(1,1,1,0,0,0,0,0,0),
483
array(1,0,0,1,0,0,0,0,0),
484
array(1,0,0,0,1,0,0,0,0),
485
array(1,0,0,0,0,1,0,0,0),
486
array(1,0,0,0,0,0,1,0,0),
487
array(1,0,0,0,0,0,0,1,0),
488
array(1,0,0,0,0,0,0,0,1),
491
array(0,0,1,1,1,1,1,0,0),
492
array(0,1,0,0,0,0,0,1,0),
493
array(1,0,0,0,0,0,0,0,1),
494
array(1,0,0,0,0,0,0,0,0),
495
array(1,0,0,0,0,0,0,0,0),
496
array(1,0,0,0,0,0,0,0,0),
497
array(0,1,0,0,0,0,0,0,0),
498
array(0,0,1,1,1,1,1,0,0),
499
array(0,0,0,0,0,0,0,1,0),
500
array(0,0,0,0,0,0,0,0,1),
501
array(0,0,0,0,0,0,0,0,1),
502
array(0,0,0,0,0,0,0,0,1),
503
array(1,0,0,0,0,0,0,0,1),
504
array(0,1,0,0,0,0,0,1,0),
505
array(0,0,1,1,1,1,1,0,0),
508
array(1,1,1,1,1,1,1,1,1),
509
array(0,0,0,0,1,0,0,0,0),
510
array(0,0,0,0,1,0,0,0,0),
511
array(0,0,0,0,1,0,0,0,0),
512
array(0,0,0,0,1,0,0,0,0),
513
array(0,0,0,0,1,0,0,0,0),
514
array(0,0,0,0,1,0,0,0,0),
515
array(0,0,0,0,1,0,0,0,0),
516
array(0,0,0,0,1,0,0,0,0),
517
array(0,0,0,0,1,0,0,0,0),
518
array(0,0,0,0,1,0,0,0,0),
519
array(0,0,0,0,1,0,0,0,0),
520
array(0,0,0,0,1,0,0,0,0),
521
array(0,0,0,0,1,0,0,0,0),
522
array(0,0,0,0,1,0,0,0,0),
525
array(1,0,0,0,0,0,0,0,1),
526
array(1,0,0,0,0,0,0,0,1),
527
array(1,0,0,0,0,0,0,0,1),
528
array(1,0,0,0,0,0,0,0,1),
529
array(1,0,0,0,0,0,0,0,1),
530
array(1,0,0,0,0,0,0,0,1),
531
array(1,0,0,0,0,0,0,0,1),
532
array(1,0,0,0,0,0,0,0,1),
533
array(1,0,0,0,0,0,0,0,1),
534
array(1,0,0,0,0,0,0,0,1),
535
array(1,0,0,0,0,0,0,0,1),
536
array(1,0,0,0,0,0,0,0,1),
537
array(1,0,0,0,0,0,0,0,1),
538
array(0,1,0,0,0,0,0,1,0),
539
array(0,0,1,1,1,1,1,0,0),
542
array(1,0,0,0,0,0,0,0,1),
543
array(1,0,0,0,0,0,0,0,1),
544
array(1,0,0,0,0,0,0,0,1),
545
array(0,1,0,0,0,0,0,1,0),
546
array(0,1,0,0,0,0,0,1,0),
547
array(0,1,0,0,0,0,0,1,0),
548
array(0,0,1,0,0,0,1,0,0),
549
array(0,0,1,0,0,0,1,0,0),
550
array(0,0,1,0,0,0,1,0,0),
551
array(0,0,1,0,0,0,1,0,0),
552
array(0,0,0,1,0,1,0,0,0),
553
array(0,0,0,1,0,1,0,0,0),
554
array(0,0,0,1,0,1,0,0,0),
555
array(0,0,0,0,1,0,0,0,0),
556
array(0,0,0,0,1,0,0,0,0),
558
'W' => array( // New 'W', supplied by MHobbit
559
array(1,0,0,0,0,0,0,0,1),
560
array(1,0,0,0,0,0,0,0,1),
561
array(1,0,0,0,0,0,0,0,1),
562
array(1,0,0,0,0,0,0,0,1),
563
array(1,0,0,0,0,0,0,0,1),
564
array(1,0,0,0,1,0,0,0,1),
565
array(1,0,0,0,1,0,0,0,1),
566
array(1,0,0,1,0,1,0,0,1),
567
array(1,0,0,1,0,1,0,0,1),
568
array(1,0,0,1,0,1,0,0,1),
569
array(1,0,1,0,0,0,1,0,1),
570
array(1,0,1,0,0,0,1,0,1),
571
array(1,0,1,0,0,0,1,0,1),
572
array(1,1,0,0,0,0,0,1,1),
573
array(1,1,0,0,0,0,0,1,1),
576
array(1,0,0,0,0,0,0,0,1),
577
array(1,0,0,0,0,0,0,0,1),
578
array(0,1,0,0,0,0,0,1,0),
579
array(0,1,0,0,0,0,0,1,0),
580
array(0,0,1,0,0,0,1,0,0),
581
array(0,0,0,1,0,1,0,0,0),
582
array(0,0,0,1,0,1,0,0,0),
583
array(0,0,0,0,1,0,0,0,0),
584
array(0,0,0,1,0,1,0,0,0),
585
array(0,0,0,1,0,1,0,0,0),
586
array(0,0,1,0,0,0,1,0,0),
587
array(0,1,0,0,0,0,1,0,0),
588
array(0,1,0,0,0,0,0,1,0),
589
array(1,0,0,0,0,0,0,0,1),
590
array(1,0,0,0,0,0,0,0,1),
593
array(1,0,0,0,0,0,0,0,1),
594
array(1,0,0,0,0,0,0,0,1),
595
array(0,1,0,0,0,0,0,1,0),
596
array(0,1,0,0,0,0,0,1,0),
597
array(0,0,1,0,0,0,1,0,0),
598
array(0,0,1,0,0,0,1,0,0),
599
array(0,0,0,1,0,1,0,0,0),
600
array(0,0,0,0,1,0,0,0,0),
601
array(0,0,0,0,1,0,0,0,0),
602
array(0,0,0,0,1,0,0,0,0),
603
array(0,0,0,0,1,0,0,0,0),
604
array(0,0,0,0,1,0,0,0,0),
605
array(0,0,0,0,1,0,0,0,0),
606
array(0,0,0,0,1,0,0,0,0),
607
array(0,0,0,0,1,0,0,0,0),
609
'Z' => array( // New 'Z' supplied by Anon
610
array(1,1,1,1,1,1,1,1,1),
611
array(1,0,0,0,0,0,0,0,1),
612
array(0,0,0,0,0,0,0,0,1),
613
array(0,0,0,0,0,0,0,1,0),
614
array(0,0,0,0,0,0,1,0,0),
615
array(0,0,0,0,0,1,0,0,0),
616
array(0,0,0,0,0,1,0,0,0),
617
array(0,0,0,0,1,0,0,0,0),
618
array(0,0,0,1,0,0,0,0,0),
619
array(0,0,0,1,0,0,0,0,0),
620
array(0,0,1,0,0,0,0,0,0),
621
array(0,1,0,0,0,0,0,0,0),
622
array(1,0,0,0,0,0,0,0,0),
623
array(1,0,0,0,0,0,0,0,1),
624
array(1,1,1,1,1,1,1,1,1),
627
array(0,0,0,1,1,0,0,0,0),
628
array(0,0,1,0,1,0,0,0,0),
629
array(0,1,0,0,1,0,0,0,0),
630
array(0,0,0,0,1,0,0,0,0),
631
array(0,0,0,0,1,0,0,0,0),
632
array(0,0,0,0,1,0,0,0,0),
633
array(0,0,0,0,1,0,0,0,0),
634
array(0,0,0,0,1,0,0,0,0),
635
array(0,0,0,0,1,0,0,0,0),
636
array(0,0,0,0,1,0,0,0,0),
637
array(0,0,0,0,1,0,0,0,0),
638
array(0,0,0,0,1,0,0,0,0),
639
array(0,0,0,0,1,0,0,0,0),
640
array(0,0,0,0,1,0,0,0,0),
641
array(0,1,1,1,1,1,1,1,0),
643
'2' => array( // New '2' supplied by Anon
644
array(0,0,0,1,1,1,0,0,0),
645
array(0,0,1,0,0,0,1,0,0),
646
array(0,1,0,0,0,0,1,1,0),
647
array(0,0,0,0,0,0,0,0,1),
648
array(0,0,0,0,0,0,0,0,1),
649
array(0,0,0,0,0,0,0,1,1),
650
array(0,0,0,0,0,0,0,1,0),
651
array(0,0,0,0,0,0,1,0,0),
652
array(0,0,0,0,0,1,0,0,0),
653
array(0,0,0,0,1,0,0,0,0),
654
array(0,0,0,1,0,0,0,0,0),
655
array(0,0,1,0,0,0,0,0,0),
656
array(0,1,0,0,0,0,0,0,0),
657
array(1,1,1,1,1,1,1,1,1),
658
array(0,0,0,0,0,0,0,0,0),
661
array(0,0,1,1,1,1,1,0,0),
662
array(0,1,0,0,0,0,0,1,0),
663
array(1,0,0,0,0,0,0,0,1),
664
array(0,0,0,0,0,0,0,0,1),
665
array(0,0,0,0,0,0,0,0,1),
666
array(0,0,0,0,0,0,0,0,1),
667
array(0,0,0,0,0,0,0,1,0),
668
array(0,0,0,0,0,1,1,0,0),
669
array(0,0,0,0,0,0,0,1,0),
670
array(0,0,0,0,0,0,0,0,1),
671
array(0,0,0,0,0,0,0,0,1),
672
array(0,0,0,0,0,0,0,0,1),
673
array(1,0,0,0,0,0,0,0,1),
674
array(0,1,0,0,0,0,0,1,0),
675
array(0,0,1,1,1,1,1,0,0),
678
array(0,0,0,0,0,0,1,1,0),
679
array(0,0,0,0,0,1,0,1,0),
680
array(0,0,0,0,1,0,0,1,0),
681
array(0,0,0,1,0,0,0,1,0),
682
array(0,0,1,0,0,0,0,1,0),
683
array(0,1,0,0,0,0,0,1,0),
684
array(1,0,0,0,0,0,0,1,0),
685
array(1,0,0,0,0,0,0,1,0),
686
array(1,1,1,1,1,1,1,1,1),
687
array(0,0,0,0,0,0,0,1,0),
688
array(0,0,0,0,0,0,0,1,0),
689
array(0,0,0,0,0,0,0,1,0),
690
array(0,0,0,0,0,0,0,1,0),
691
array(0,0,0,0,0,0,0,1,0),
692
array(0,0,0,0,0,0,0,1,0),
695
array(1,1,1,1,1,1,1,1,1),
696
array(1,0,0,0,0,0,0,0,0),
697
array(1,0,0,0,0,0,0,0,0),
698
array(1,0,0,0,0,0,0,0,0),
699
array(1,0,0,0,0,0,0,0,0),
700
array(0,1,0,0,0,0,0,0,0),
701
array(0,0,1,1,1,1,1,0,0),
702
array(0,0,0,0,0,0,0,1,0),
703
array(0,0,0,0,0,0,0,0,1),
704
array(0,0,0,0,0,0,0,0,1),
705
array(0,0,0,0,0,0,0,0,1),
706
array(0,0,0,0,0,0,0,0,1),
707
array(1,0,0,0,0,0,0,0,1),
708
array(0,1,0,0,0,0,0,1,0),
709
array(0,0,1,1,1,1,1,0,0),
712
array(0,0,1,1,1,1,1,0,0),
713
array(0,1,0,0,0,0,0,1,0),
714
array(1,0,0,0,0,0,0,0,1),
715
array(1,0,0,0,0,0,0,0,1),
716
array(1,0,0,0,0,0,0,0,0),
717
array(1,0,0,0,0,0,0,0,0),
718
array(1,0,0,1,1,1,1,0,0),
719
array(1,0,1,0,0,0,0,1,0),
720
array(1,1,0,0,0,0,0,0,1),
721
array(1,0,0,0,0,0,0,0,1),
722
array(1,0,0,0,0,0,0,0,1),
723
array(1,0,0,0,0,0,0,0,1),
724
array(1,0,0,0,0,0,0,0,1),
725
array(0,1,0,0,0,0,0,1,0),
726
array(0,0,1,1,1,1,1,0,0),
729
array(1,1,1,1,1,1,1,1,1),
730
array(0,0,0,0,0,0,0,0,1),
731
array(0,0,0,0,0,0,0,1,0),
732
array(0,0,0,0,0,0,0,1,0),
733
array(0,0,0,0,0,0,1,0,0),
734
array(0,0,0,0,0,1,0,0,0),
735
array(0,0,0,0,0,1,0,0,0),
736
array(0,0,0,0,1,0,0,0,0),
737
array(0,0,0,1,0,0,0,0,0),
738
array(0,0,0,1,0,0,0,0,0),
739
array(0,0,1,0,0,0,0,0,0),
740
array(0,1,0,0,0,0,0,0,0),
741
array(0,1,0,0,0,0,0,0,0),
742
array(1,0,0,0,0,0,0,0,0),
743
array(1,0,0,0,0,0,0,0,0),
746
array(0,0,1,1,1,1,1,0,0),
747
array(0,1,0,0,0,0,0,1,0),
748
array(1,0,0,0,0,0,0,0,1),
749
array(1,0,0,0,0,0,0,0,1),
750
array(1,0,0,0,0,0,0,0,1),
751
array(1,0,0,0,0,0,0,0,1),
752
array(0,1,0,0,0,0,0,1,0),
753
array(0,0,1,1,1,1,1,0,0),
754
array(0,1,0,0,0,0,0,1,0),
755
array(1,0,0,0,0,0,0,0,1),
756
array(1,0,0,0,0,0,0,0,1),
757
array(1,0,0,0,0,0,0,0,1),
758
array(1,0,0,0,0,0,0,0,1),
759
array(0,1,0,0,0,0,0,1,0),
760
array(0,0,1,1,1,1,1,0,0),
763
array(0,0,1,1,1,1,1,0,0),
764
array(0,1,0,0,0,0,0,1,0),
765
array(1,0,0,0,0,0,0,0,1),
766
array(1,0,0,0,0,0,0,0,1),
767
array(1,0,0,0,0,0,0,0,1),
768
array(1,0,0,0,0,0,0,0,1),
769
array(1,0,0,0,0,0,0,1,1),
770
array(0,1,0,0,0,0,1,0,1),
771
array(0,0,1,1,1,1,0,0,1),
772
array(0,0,0,0,0,0,0,0,1),
773
array(0,0,0,0,0,0,0,0,1),
774
array(1,0,0,0,0,0,0,0,1),
775
array(1,0,0,0,0,0,0,0,1),
776
array(0,1,0,0,0,0,0,1,0),
777
array(0,0,1,1,1,1,1,0,0),
793
var $basis_matrix = array(array(1, 0, 0), array(0, 1, 0), array(0, 0, 1));
794
var $abs_x = array(1, 0);
795
var $abs_y = array(0, 1);
803
function char_cube3d(&$bitmaps, $letter)
805
$this->bitmap = $bitmaps['data'][$letter];
806
$this->bitmap_width = $bitmaps['width'];
807
$this->bitmap_height = $bitmaps['height'];
809
$this->basis_matrix[0][0] = mt_rand(-600, 600);
810
$this->basis_matrix[0][1] = mt_rand(-600, 600);
811
$this->basis_matrix[0][2] = (mt_rand(0, 1) * 2000) - 1000;
812
$this->basis_matrix[1][0] = mt_rand(-1000, 1000);
813
$this->basis_matrix[1][1] = mt_rand(-1000, 1000);
814
$this->basis_matrix[1][2] = mt_rand(-1000, 1000);
816
$this->normalize($this->basis_matrix[0]);
817
$this->normalize($this->basis_matrix[1]);
818
$this->basis_matrix[2] = $this->cross_product($this->basis_matrix[0], $this->basis_matrix[1]);
819
$this->normalize($this->basis_matrix[2]);
821
// $this->basis_matrix[1] might not be (probably isn't) orthogonal to $basis_matrix[0]
822
$this->basis_matrix[1] = $this->cross_product($this->basis_matrix[0], $this->basis_matrix[2]);
823
$this->normalize($this->basis_matrix[1]);
825
// Make sure our cube is facing into the canvas (assuming +z == in)
826
for ($i = 0; $i < 3; ++$i)
828
if ($this->basis_matrix[$i][2] < 0)
830
$this->basis_matrix[$i][0] *= -1;
831
$this->basis_matrix[$i][1] *= -1;
832
$this->basis_matrix[$i][2] *= -1;
836
// Force our "z" basis vector to be the one with greatest absolute z value
842
if ($this->basis_matrix[1][2] > $this->basis_matrix[2][2])
849
if ($this->basis_matrix[0][2] > $this->basis_matrix[$this->z][2])
855
// Still need to determine which of $x,$y are which.
856
// wrong orientation if y's y-component is less than it's x-component
857
// likewise if x's x-component is less than it's y-component
858
// if they disagree, go with the one with the greater weight difference.
859
// rotate if positive
860
$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]));
865
list($this->x, $this->y) = array($this->y, $this->x);
868
$this->abs_x = array($this->basis_matrix[$this->x][0], $this->basis_matrix[$this->x][1]);
869
$this->abs_y = array($this->basis_matrix[$this->y][0], $this->basis_matrix[$this->y][1]);
871
if ($this->abs_x[0] < 0)
873
$this->abs_x[0] *= -1;
874
$this->abs_x[1] *= -1;
877
if ($this->abs_y[1] > 0)
879
$this->abs_y[0] *= -1;
880
$this->abs_y[1] *= -1;
883
$this->letter = $letter;
889
function drawchar($scale, $xoff, $yoff, $img, $background, $colours)
891
$width = $this->bitmap_width;
892
$height = $this->bitmap_height;
893
$bitmap = $this->bitmap;
895
$colour1 = $colours[array_rand($colours)];
896
$colour2 = $colours[array_rand($colours)];
898
$swapx = ($this->basis_matrix[$this->x][0] > 0);
899
$swapy = ($this->basis_matrix[$this->y][1] < 0);
901
for ($y = 0; $y < $height; ++$y)
903
for ($x = 0; $x < $width; ++$x)
905
$xp = ($swapx) ? ($width - $x - 1) : $x;
906
$yp = ($swapy) ? ($height - $y - 1) : $y;
908
if ($bitmap[$height - $yp - 1][$xp])
910
$dx = $this->scale($this->abs_x, ($xp - ($swapx ? ($width / 2) : ($width / 2) - 1)) * $scale);
911
$dy = $this->scale($this->abs_y, ($yp - ($swapy ? ($height / 2) : ($height / 2) - 1)) * $scale);
912
$xo = $xoff + $dx[0] + $dy[0];
913
$yo = $yoff + $dx[1] + $dy[1];
915
$origin = array(0, 0, 0);
916
$xvec = $this->scale($this->basis_matrix[$this->x], $scale);
917
$yvec = $this->scale($this->basis_matrix[$this->y], $scale);
918
$face_corner = $this->sum2($xvec, $yvec);
920
$zvec = $this->scale($this->basis_matrix[$this->z], $scale);
921
$x_corner = $this->sum2($xvec, $zvec);
922
$y_corner = $this->sum2($yvec, $zvec);
924
imagefilledpolygon($img, $this->gen_poly($xo, $yo, $origin, $xvec, $x_corner,$zvec), 4, $colour1);
925
imagefilledpolygon($img, $this->gen_poly($xo, $yo, $origin, $yvec, $y_corner,$zvec), 4, $colour2);
927
$face = $this->gen_poly($xo, $yo, $origin, $xvec, $face_corner, $yvec);
929
imagefilledpolygon($img, $face, 4, $background);
930
imagepolygon($img, $face, 4, $colour1);
937
* return a roughly acceptable range of sizes for rendering with this texttype
947
function vectorlen($vector)
949
return sqrt(pow($vector[0], 2) + pow($vector[1], 2) + pow($vector[2], 2));
955
function normalize(&$vector, $length = 1)
957
$length = (( $length < 1) ? 1 : $length);
958
$length /= $this->vectorlen($vector);
959
$vector[0] *= $length;
960
$vector[1] *= $length;
961
$vector[2] *= $length;
966
function cross_product($vector1, $vector2)
968
$retval = array(0, 0, 0);
969
$retval[0] = (($vector1[1] * $vector2[2]) - ($vector1[2] * $vector2[1]));
970
$retval[1] = -(($vector1[0] * $vector2[2]) - ($vector1[2] * $vector2[0]));
971
$retval[2] = (($vector1[0] * $vector2[1]) - ($vector1[1] * $vector2[0]));
978
function sum($vector1, $vector2)
980
return array($vector1[0] + $vector2[0], $vector1[1] + $vector2[1], $vector1[2] + $vector2[2]);
985
function sum2($vector1, $vector2)
987
return array($vector1[0] + $vector2[0], $vector1[1] + $vector2[1]);
992
function scale($vector, $length)
994
if (sizeof($vector) == 2)
996
return array($vector[0] * $length, $vector[1] * $length);
999
return array($vector[0] * $length, $vector[1] * $length, $vector[2] * $length);
1004
function gen_poly($xoff, $yoff, &$vec1, &$vec2, &$vec3, &$vec4)
1007
$poly[0] = $xoff + $vec1[0];
1008
$poly[1] = $yoff + $vec1[1];
1009
$poly[2] = $xoff + $vec2[0];
1010
$poly[3] = $yoff + $vec2[1];
1011
$poly[4] = $xoff + $vec3[0];
1012
$poly[5] = $yoff + $vec3[1];
1013
$poly[6] = $xoff + $vec4[0];
1014
$poly[7] = $yoff + $vec4[1];
1022
function dimensions($size)
1024
$xn = $this->scale($this->basis_matrix[$this->x], -($this->bitmap_width / 2) * $size);
1025
$xp = $this->scale($this->basis_matrix[$this->x], ($this->bitmap_width / 2) * $size);
1026
$yn = $this->scale($this->basis_matrix[$this->y], -($this->bitmap_height / 2) * $size);
1027
$yp = $this->scale($this->basis_matrix[$this->y], ($this->bitmap_height / 2) * $size);
1030
$p[0] = $this->sum2($xn, $yn);
1031
$p[1] = $this->sum2($xp, $yn);
1032
$p[2] = $this->sum2($xp, $yp);
1033
$p[3] = $this->sum2($xn, $yp);
1035
$min_x = $max_x = $p[0][0];
1036
$min_y = $max_y = $p[0][1];
1038
for ($i = 1; $i < 4; ++$i)
1040
$min_x = ($min_x > $p[$i][0]) ? $p[$i][0] : $min_x;
1041
$min_y = ($min_y > $p[$i][1]) ? $p[$i][1] : $min_y;
1042
$max_x = ($max_x < $p[$i][0]) ? $p[$i][0] : $max_x;
1043
$max_y = ($max_y < $p[$i][1]) ? $p[$i][1] : $max_y;
1046
return array($min_x, $min_y, $max_x, $max_y);
1053
class colour_manager
1061
* Create the colour manager, link it to the image resource
1063
function colour_manager($img, $background = false, $mode = 'ahsv')
1066
$this->mode = $mode;
1067
$this->colours = array();
1068
$this->named_colours = array();
1070
if ($background !== false)
1072
$bg = $this->allocate_named('background', $background);
1073
imagefill($this->img, 0, 0, $bg);
1078
* Lookup a named colour resource
1080
function get_resource($named_colour)
1082
if (isset($this->named_colours[$named_colour]))
1084
return $this->named_colours[$named_colour];
1087
if (isset($this->named_rgb[$named_colour]))
1089
return $this->allocate_named($named_colour, $this->named_rgb[$named_colour], 'rgb');
1096
* Assign a name to a colour resource
1098
function name_colour($name, $resource)
1100
$this->named_colours[$name] = $resource;
1104
* names and allocates a colour resource
1106
function allocate_named($name, $colour, $mode = false)
1108
$resource = $this->allocate($colour, $mode);
1110
if ($resource !== false)
1112
$this->name_colour($name, $resource);
1118
* allocates a specified colour into the image
1120
function allocate($colour, $mode = false)
1122
if ($mode === false)
1124
$mode = $this->mode;
1127
if (!is_array($colour))
1129
if (isset($this->named_rgb[$colour]))
1131
return $this->allocate_named($colour, $this->named_rgb[$colour], 'rgb');
1134
if (!is_int($colour))
1140
$colour = array(255 & ($colour >> 16), 255 & ($colour >> 8), 255 & $colour);
1143
if (isset($colour['mode']))
1145
$mode = $colour['mode'];
1146
unset($colour['mode']);
1149
if (isset($colour['random']))
1151
unset($colour['random']);
1152
// everything else is params
1153
return $this->random_colour($colour, $mode);
1156
$rgb = colour_manager::model_convert($colour, $mode, 'rgb');
1157
$store = ($this->mode == 'rgb') ? $rgb : colour_manager::model_convert($colour, $mode, $this->mode);
1158
$resource = imagecolorallocate($this->img, $rgb[0], $rgb[1], $rgb[2]);
1159
$this->colours[$resource] = $store;
1165
* randomly generates a colour, with optional params
1167
function random_colour($params = array(), $mode = false)
1169
if ($mode === false)
1171
$mode = $this->mode;
1177
// @TODO random rgb generation. do we intend to do this, or is it just too tedious?
1184
$default_params = array(
1185
'hue_bias' => false, // degree / 'r'/'g'/'b'/'c'/'m'/'y' /'o'
1186
'hue_range' => false, // if hue bias, then difference range +/- from bias
1187
'min_saturation' => 30, // 0 - 100
1188
'max_saturation' => 80, // 0 - 100
1189
'min_value' => 30, // 0 - 100
1190
'max_value' => 80, // 0 - 100
1193
$alt = ($mode == 'ahsv') ? true : false;
1194
$params = array_merge($default_params, $params);
1198
$min_saturation = max(0, $params['min_saturation']);
1199
$max_saturation = min(100, $params['max_saturation']);
1200
$min_value = max(0, $params['min_value']);
1201
$max_value = min(100, $params['max_value']);
1203
if ($params['hue_bias'] !== false)
1205
if (is_numeric($params['hue_bias']))
1207
$h = intval($params['hue_bias']) % 360;
1211
switch ($params['hue_bias'])
1214
$h = $alt ? 60 : 30;
1218
$h = $alt ? 120 : 60;
1222
$h = $alt ? 180 : 120;
1226
$h = $alt ? 210 : 180;
1244
$min_hue = $h + 360;
1245
$max_hue = $h + 360;
1247
if ($params['hue_range'])
1249
$min_hue -= min(180, $params['hue_range']);
1250
$max_hue += min(180, $params['hue_range']);
1254
$h = mt_rand($min_hue, $max_hue);
1255
$s = mt_rand($min_saturation, $max_saturation);
1256
$v = mt_rand($min_value, $max_value);
1258
return $this->allocate(array($h, $s, $v), $mode);
1266
function colour_scheme($resource, $include_original = true)
1270
if (($pre = $this->get_resource($resource)) !== false)
1275
$colour = colour_manager::model_convert($this->colours[$resource], $this->mode, $mode);
1276
$results = ($include_original) ? array($resource) : array();
1277
$colour2 = $colour3 = $colour4 = $colour;
1283
$results[] = $this->allocate($colour2, $mode);
1284
$results[] = $this->allocate($colour3, $mode);
1285
$results[] = $this->allocate($colour4, $mode);
1292
function mono_range($resource, $count = 5, $include_original = true)
1294
if (is_array($resource))
1297
for ($i = 0, $size = sizeof($resource); $i < $size; ++$i)
1299
$results = array_merge($results, $this->mono_range($resource[$i], $count, $include_original));
1304
$mode = (in_array($this->mode, array('hsv', 'ahsv'), true) ? $this->mode : 'ahsv');
1305
if (($pre = $this->get_resource($resource)) !== false)
1310
$colour = colour_manager::model_convert($this->colours[$resource], $this->mode, $mode);
1313
if ($include_original)
1315
$results[] = $resource;
1319
// This is a hard problem. I chicken out and try to maintain readability at the cost of less randomness.
1323
$colour[1] = ($colour[1] + mt_rand(40,60)) % 99;
1324
$colour[2] = ($colour[2] + mt_rand(40,60));
1325
$results[] = $this->allocate($colour, $mode);
1332
* Convert from one colour model to another
1334
function model_convert($colour, $from_model, $to_model)
1336
if ($from_model == $to_model)
1345
switch ($from_model)
1348
return colour_manager::ah2h($colour);
1352
return colour_manager::rgb2hsv($colour);
1359
switch ($from_model)
1362
return colour_manager::h2ah($colour);
1366
return colour_manager::h2ah(colour_manager::rgb2hsv($colour));
1372
switch ($from_model)
1375
return colour_manager::hsv2rgb($colour);
1379
return colour_manager::hsv2rgb(colour_manager::ah2h($colour));
1388
* Slightly altered from wikipedia's algorithm
1390
function hsv2rgb($hsv)
1392
colour_manager::normalize_hue($hsv[0]);
1395
$s = min(1, max(0, $hsv[1] / 100));
1396
$v = min(1, max(0, $hsv[2] / 100));
1398
// calculate hue sector
1399
$hi = floor($hsv[0] / 60);
1401
// calculate opposite colour
1404
// calculate distance between hex vertices
1405
$f = ($h / 60) - $hi;
1407
// coming in or going out?
1413
// calculate adjacent colour
1414
$q = $v * (1 - ($f * $s));
1419
$rgb = array($v, $q, $p);
1423
$rgb = array($q, $v, $p);
1427
$rgb = array($p, $v, $q);
1431
$rgb = array($p, $q, $v);
1435
$rgb = array($q, $p, $v);
1439
$rgb = array($v, $p, $q);
1443
return array(0, 0, 0);
1447
return array(255 * $rgb[0], 255 * $rgb[1], 255 * $rgb[2]);
1451
* (more than) Slightly altered from wikipedia's algorithm
1453
function rgb2hsv($rgb)
1455
$r = min(255, max(0, $rgb[0]));
1456
$g = min(255, max(0, $rgb[1]));
1457
$b = min(255, max(0, $rgb[2]));
1458
$max = max($r, $g, $b);
1459
$min = min($r, $g, $b);
1462
$s = (!$max) ? 0 : 1 - ($min / $max);
1464
// if max - min is 0, we want hue to be 0 anyway.
1472
$h = 120 + (60 * ($b - $r) / $h);
1476
$h = 240 + (60 * ($r - $g) / $h);
1480
$h = 360 + (60 * ($g - $b) / $h);
1484
colour_manager::normalize_hue($h);
1486
return array($h, $s * 100, $v * 100);
1491
function normalize_hue(&$hue)
1502
* Alternate hue to hue
1504
function ah2h($ahue)
1506
if (is_array($ahue))
1508
$ahue[0] = colour_manager::ah2h($ahue[0]);
1511
colour_manager::normalize_hue($ahue);
1513
// blue through red is already ok
1519
// ahue green is at 180
1522
// return (240 - (2 * (240 - $ahue)));
1523
return (2 * $ahue) - 240; // equivalent
1526
// ahue yellow is at 120 (RYB rather than RGB)
1536
* hue to Alternate hue
1542
$hue[0] = colour_manager::h2ah($hue[0]);
1545
colour_manager::normalize_hue($hue);
1547
// blue through red is already ok
1552
else if ($hue <= 60)
1556
else if ($hue <= 120)
1562
return ($hue + 240) / 2;
b'\\ No newline at end of file'