<?php

header ("Content-type: image/svg+xml");

// ---------------------------------------------------------------------
//
// Mark Brautigam
// 18 Feb. 2015
//
// use like this:
// <img alt='A' src='letters.php?n=A&c=f80' />
//
// To do:
// 4. Add numbers
// 5. Do the scale conversions in PHP instead of in SVG
// 6. Convert some bezier curves to arcs?
// 7. Add real lower case letters?
// 8. Print a whole message of several letters in one block
// 9. Convert the whole thing to Javasript

// Notes:
// 2. You must specify the background color using 3-digit hex without the #
//    a. use c=xyz where xyz is the hex color
//    b. E.g. f00 = red, 0f0 = green, 00f = blue
//    c. The program will add # automatically
//    d. The program will calculate a suitable contrasting color for the
//       letters, either black or white
//
// DONE:
// 1. Convert lower case to upper case letters for now until we have a
//    real set of lower case letters
// 3. Let them specify color in 6-digit hex
//
// ---------------------------------------------------------------------

$letter = /*strtoupper*/ ($_GET['n']);
$color  = '#' . $_GET['c'];
if (strlen ($color) > 7) $color = substr ($color, 0, 7);
$textColor = contrastingColor ($color);

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting (E_ALL);

function contrastingColor ($c)
{
  if (strlen ($c) != 7) {
    $r = hexdec ($c[1]) / 16;
    $g = hexdec ($c[2]) / 16;
    $b = hexdec ($c[3]) / 16;
  }
  else {
    $r = (hexdec ($c[1]) * 16 + hexdec($c[2]) ) / 256;;
    $g = (hexdec ($c[3]) * 16 + hexdec($c[4]) ) / 256;;
    $b = (hexdec ($c[5]) * 16 + hexdec($c[6]) ) / 256;;
  }
  $luma = 0.30  * $r + 0.59 * $g + 0.11 * $b;
  if ($luma > 0.5)
    return ("#000");
  else
    return ("#fff");
  /*
  $max = max ($r, $g, $b);
  $min = min ($r, $g, $b);
  $r0 = $r1 = $r; $g0 = $g1 = $g; $b0 = $b1 = $b;
  if ($r0 == $max) $r0 = 15;
  if ($g0 == $max) $g0 = 15;
  if ($b0 == $max) $b0 = 15;
  if ($r1 == $min) $r1 = 0;
  if ($g1 == $min) $g1 = 0;
  if ($b1 == $min) $b1 = 0;
  if ($luma > 0.5)
    return sprintf ("#%x%x%x", $r0, $g0, $b0);
  else
    return sprintf ("#%x%x%x", $r1, $g1, $b1);
  */
}

$letters = array  (
  "A" => array ( "PL", "0 1000 500 0 1000 1000", "PL", "200 700 800 700" ),
  "B" => array ( "PL", "0 0 0 1000", "P", "M 0 0 C 500 0 1000 0 1000 240 C 1000 480 500 480 0 480",
                                     "P", "M 0 480 C 500 480 1000 480 1000 750 C 1000 1000 500 1000 0 1000" ),
  "C" => array ( "P", "M 1000 100 A 750 500 0 1 0 1000 900" ),
  "D" => array ( "PL", "0 0 0 1000", "P", "M 0 0 C 500 0 1000 0 1000 500 C 1000 1000 500 1000 0 1000" ),
  "E" => array ( "PL", "1000 0 0 0 0 1000 1000 1000", "PL", "0 475 600 475" ),
  "F" => array ( "PL", "1000 0 0 0 0 1000", "PL", "0 475 600 475" ),
  "G" => array ( "P", "M 1000 100 A 750 500 0 1 0 1000 900 L 1000 600 L 600 600" ),
  "H" => array ( "PL", "0 0 0 1000", "PL", "1000 0 1000 1000", "PL", "0 500 1000 500" ),
  "I" => array ( "PL", "200 0 800 0", "PL", "200 1000 800 1000", "PL", "500 0 500 1000" ),
  "J" => array ("PL", "700 0 1000 0 1000 600", "P", "M 0 600 C 0 1100 1000 1100 1000 600" ),
  "K" => array ( "PL", "0 0 0 1000", "PL", "1000 0 0 500 1000 1000" ),
  "L" => array ( "PL", "0 0 0 1000 1000 1000" ),
  "M" => array ( "PL", "0 1000 0 0 500 1000 1000 0 1000 1000" ),
  "N" => array ( "PL", "0 1000 0 0 1000 1000 1000 0" ),
  "O" => array ( "C", "500 500 500" ),
  "P" => array ( "PL", "0 0 0 1000", "P", "M 0 0 C 500 0 1000 0 1000 250 C 1000 500 500 500 0 500" ),
  "Q" => array ( "C", "500 500 500", "PL", "700 700 1000 1000" ),
  "R" => array ( "PL", "0 0 0 1000", "P", "M 0 0 C 500 0 1000 0 1000 250 C 1000 500 500 500 0 500", "PL", "0 500 1000 1000" ),
  "S" => array ( "P", "M 1000 250 C 1000 125 750 0 500 0 C 250 0 0 125 0 250 C 0 375 250 500 500 500 C 750 500 1000 625 1000 750 C 1000 875 750 1000 500 1000 C 250 1000 0 875 0 750" ),
  "T" => array ( "PL", "0 0 1000 0", "PL", "500 0 500 1000" ),
  "U" => array ("PL", "0 0 0 600", "PL", "1000 0 1000 600", "P", "M 0 600 C 0 1100 1000 1100 1000 600" ),
  "V" => array ( "PL", "0 0 500 1000 1000 0" ),
  "W" => array ( "PL", "0 0 250 1000 500 0 750 1000 1000 0" ),
  "X" => array ( "PL", "0 0 1000 1000", "PL", "0 1000 1000 0" ),
  "Y" => array ( "PL", "0 0 500 500 1000 0", "PL", "500 500 500 1000" ),
  "Z" => array ( "PL", "0 0 1000 0 0 1000 1000 1000" ),
  "_" => array ( ),

  // NUMBERS
  "1" => array ( "PL", "200 75 500 0 500 1000" ),
  "4" => array ( "PL", "750 1000 750 0 0 650 1000 650" ),
  "7" => array ( "PL", "0 0 1000 0 250 1000 " ),
  "0" => array ( "C", "500 500 500", "PL", "830 170 170 830" ),
  "3" => array ( "P", "M 0 250 A 500 225 0 1 1 500 450 A 500 275 0 1 1 0 750" ),
  "2" => array ( "P", "M 0 250 C 0 -100 1000 -100 1000 250 C 1000 400 550 475 500 500 C 400 525 0 700 0 1000 L 1000 1000" ),
  "8" => array ( "E", "500 225 500 225", "E", "500 725 500 275" ),
  "5" => array ( "P", "M 1000 0 L 0 0 L 0 400" ,
                      "P", "M 0 400 C 500 400 1000 400 1000 700 C 1000 1000 500 1000 0 1000" ),
  "6" => array ( "P", "M 900 0 C 300 0 0 100 0 500 L 0 700", "E", "500 700 500 300" ),
  "9" => array ( "P", "M 100 1000 C 700 1000 1000 900 1000 500 L 1000 300", "E", "500 300 500 300" ),

  // LOWER CASE
  "b" => array ( "E", "500 700 500 300", "PL", "0 0 0 1000" ),
  "d" => array ( "E", "500 700 500 300", "PL", "1000 0 1000 1000" ),
  "p" => array ( "E", "500 550 500 300", "PL", "0 250 0 1250" ),
  "q" => array ( "E", "500 550 500 300", "PL", "1000 250 1000 1250" ),
  "k" => array ( "PL", "0 0 0 1000", "PL", "1000 400 0 700 1000 1000" ),
  "l" => array ( "PL", "200 0 500 0 500 1000 200 1000 800 1000" ),
  "v" => array ( "PL", "100 400 500 1000 900 400" ),
  "w" => array ( "PL", "0 400 250 1000 500 400 750 1000 1000 400" ),
  "x" => array ( "PL", "100 400 900 1000", "PL", "100 1000 900 400" ),
  "y" => array ( "PL", "0 400 500 1000", "PL", "1000 400 0 1600" ),
  "z" => array ( "PL", "100 400 900 400 100 1000 900 1000" ),
  "i" => array ( "PL", "200 400 500 400 500 1000 200 1000 800 1000", "PL", "450 225 450 226" ),
  "o" => array ( "E", "500 700 500 300" ),
  "c" => array ( "P", "M 1000 500 A 600 300 0 1 0 1000 900" ),
  "e" => array ( "P", "M 1000 500 A 600 300 0 1 0 1000 900", "PL", "1000 500 110 900" ),
  "j" => array ( "PL", "625 400 625 900", "PL", "625 225 625 226", "P", "M 625 900 C 625 1100 375 1200 125 1200" ),
  "n" => array ( "PL", "100 400 100 1000", "P", "M 100 1000 L 100 600 C 100 320 900 320 900 600 L 900 1000" ),
  "h" => array ( "PL", "100 0 100 1000", "P", "M 100 1000 L 100 600 C 100 320 900 320 900 600 L 900 1000" ),
  "m" => array ( "PL", "0 400 0 1000", "P", "M 0 1000 L 0 600 C 0 320 500 320 500 600 L 500 1000",
                                       "P", "M 500 1000 L 500 600 C 500 320 1000 320 1000 600 L 1000 1000" ),
  "g" => array ( "E", "500 550 500 300", "PL", "1000 250 1000 900",
                                          "P", "M 1000 900 C 1000 1200 500 1200 0 1200" ),
  "r" => array ( "PL", "100 400 100 1000", "P", "M 100 1000 L 100 600 C 100 320 900 320 900 600 " ),
  "u" => array ( "PL", "900 400 900 1000", "P", "M 100 400 L 100 800 C 100 1080 900 1080 900 800 L 900 400" ),
  "t" => array ( "P", "M 400 0 L 400 750 C 400 750 400 1000 900 1000", "PL", "0 400 900 400" ),
  "f" => array ( "P", "M 400 1000 L 400 250 C 400 250 400 0 900 0", "PL", "0 500 900 500" ),
  "s" => array ( "P", "M 900 550 C 900 475 750 400 500 400 C 250 400 100 475 100 550 C 100 625 250 700 500 700 C 750 700 900 775 900 850 C 900 925 750 1000 500 1000 C 250 1000 100 925 100 850" ),
  "a" => array ( "E", "500 700 500 300", "PL", "1000 400 1000 1000"),

  // PUNCTUATION
  "-" => array ( "PL", "0 500 1000 500" ),
  "|" => array ( "PL", "500 0 500 1000 " ),
  "+" => array ( "PL", "0 500 1000 500",  "PL", "500 100 500 900 " ),
  "/" => array ( "PL", "1000 0 0 1000" ),
  "\\" => array ( "PL", "0 0 1000 1000" ),
  "*" => array ( "PL", "500 100 500 900", "PL", "0 300 1000 700", "PL", "1000 300 0 700" ),
  "." => array ( "PL", "500 999 500 1001" ),
  "," => array ( "PL", "520 950 480 1050" ),
  ";" => array ( "PL", "520 699 520 701", "PL", "520 950 480 1050" ),
  ":" => array ( "PL", "500 699 500 701",  "PL", "500 999 500 1001" ),
  "(" => array ( "P", "M 550 0 C 100 300 100 700 550 1000" ),
  ")" => array ( "P", "M 450 0 C 900 300 900 700 450 1000" ),
  "'" => array ( "PL", "500 0 480 50" ),
  "\"" => array ( "PL", "600 0 580 50", "PL", "400 0 380 50" ),
  "?" => array ( "P", "M 0 250 C 0 -100 1000 -100 1000 250 C 1000 400 550 475 500 700 ", "PL", "500 999 500 1001" ),
  "!" => array ( "PL", "500 0 500 700 ", "PL", "500 999 500 1001" ),
  "^" => array ( "PL", "100 400 500 0 900 400" ),
  "=" => array ( "PL", "0 300 1000 300",  "PL", "0 700 1000 700" ),
  "<" => array ( "PL", "900 0 100 500 900 1000" ),
  ">" => array ( "PL", "100 0 900 500 100 1000" ),
  "%" => array ( "C", "200 200 200", "PL", "1000 0 0 1000", "C", "800 800 200" ),
  "$" => array ( "P", "M 1000 250 C 1000 125 750 0 500 0 C 250 0 0 125 0 250 C 0 375 250 500 500 500 C 750 500 1000 625 1000 750 C 1000 875 750 1000 500 1000 C 250 1000 0 875 0 750", "PL", "500 -100 500 1100" ),
  "`" => array ( "PL", "480 0 500 50" ),
  "~" => array ( "P", "M 0 600 C 500 000 500 1000 1000 400" ),

  /* OLD STUFF
  // "C" => array ("X", "<path d='M500 0 C 250 0 0 250 0 500 C 0 750 250 1000 500 1000 C 750 1000 1000 750 1000 500' transform='rotate(45 500 500)' />"),
  // "G" => array ("X", "<path d='M500 0 C 250 0 0 250 0 500 C 0 750 250 1000 500 1000 C 750 1000 1000 750 1000 500' transform='rotate(45 500 500)' />", "PL", "853 1000 853 600 700 600" ),
  // "6" => array ( "P", "M 1000 100 C 800 0 600 0 500 0 C 100 0 0 250 0 500 L 0 700", "E", "500 700 500 300" ),
  // "9" => array ( "P", "M 0 900 C 200 1000 400 1000 500 1000 C 900 1000 1000 750 1000 500 L 1000 300", "E", "500 300 500 300" ),
  // "G" => array ("X", "<path d='M500 0 C 250 0 0 250 0 500 C 0 750 250 1000 500 1000 C 750 1000 1000 750 1000 500 L 750 250 L 500 500' transform='rotate(45 500 500)' />" ),
  */
);

function scaledown (&$a) {
    for ($i=1; $i<count($a); $i+=2) {
        // skip every other array element
        $numbers = explode (" ", $a[$i]);
        if ($a[$i-1] == "C") {
            // circle is a special case: cx cy r
            $numbers[0] = $numbers[0] * 0.4;
            $numbers[1] = $numbers[1] * 0.6;
            $numbers[2] = $numbers[2] * 0.4;
            array_push ($numbers, $numbers[2] * 1.5); // yes
            $a[$i] = implode(" ", $numbers);
            continue;
        }
        // print_r ($numbers);
        $numerics = 0;
        for ($n=0; $n<count($numbers); $n++) {
            if ($numbers[$n] == "A") {
                $numbers[$n+1] *= 0.4;
                $numbers[$n+2] *= 0.6;
                $numbers[$n+6] *= 0.4;
                $numbers[$n+7] *= 0.6;
                $n+=7;
            }
            else if (!is_numeric($numbers[$n])) 
                $numbers[$n] = $numbers[$n];
            else if ($numerics % 2 == 0) {
                $numbers[$n] *= 0.4; // x
                $numerics++;
            }
            else {
                $numbers[$n] *= 0.6; // y
                $numerics++;
            }
        }
        // print_r ($numbers);
        $newnumbers = implode(" ", $numbers);
        $a[$i] = $newnumbers;
    }
}

?>
<svg height="1000" width="1000" xmlns="http://www.w3.org/2000/svg" viewBox='0 0 1000 1000'>

<rect x='0' y='0' width='1000' height='1000' fill='<?php echo $color; ?>' />

<g stroke='<?php echo $textColor?>' stroke-width='60' stroke-linejoin='bevel' stroke-linecap='square' fill='none' 
  transform='translate(300 200)' > 
<?php
  $myLetter = $letters[$letter];
  // print_r ($myLetter);
  scaledown ($myLetter);
  // print_r ($myLetter);
  for ($i=0; $i<count($myLetter); $i++) {
    if ($myLetter[$i] == "PL")
      echo "  <polyline points='{$myLetter[$i+1]}' />\n";
    else if ($myLetter[$i] == "C") {
      $cxcyr = explode(" ", $myLetter[$i+1]);
      // print_r ($cxcyr);
      // echo "  <circle cx='{$myLetter[$i+1]}' cy='{$myLetter[$i+2]}' r='{$myLetter[$i+3]}' />\n";
      echo "  <ellipse cx='{$cxcyr[0]}' cy='{$cxcyr[1]}' rx='{$cxcyr[2]}' ry='{$cxcyr[3]}' />\n";
    }
    else if ($myLetter[$i] == "E") {
      $cxcyr = explode(" ", $myLetter[$i+1]);
      // echo "  <ellipse cx='{$myLetter[$i+1]}' cy='{$myLetter[$i+2]}' rx='{$myLetter[$i+3]}' ry='{$myLetter[$i+4]}' />\n";
      echo "  <ellipse cx='{$cxcyr[0]}' cy='{$cxcyr[1]}' rx='{$cxcyr[2]}' ry='{$cxcyr[3]}' />\n";
    }
    else if ($myLetter[$i] == "P")
      echo "  <path d='{$myLetter[$i+1]}' />\n";
    else if ($myLetter[$i] == "X")
      echo "  " . $myLetter[$i+1] . "\n";
  }
?>
</g>

</svg>