1.5) $zoom = 1; } //We should check the election progress before doing any real work. /** * NOTE: this is likely something that should be moved up into a library of some * kind, and likely the mysql database will/should be changed (1 table w/1 row * w/1 value seems kind of odd, doesn't it?) **/ //Assume we are still in the initialization phase of the election $current_status = "initialization"; global $db_dsn, $db_options; $db =& MDB2::singleton($db_dsn, $db_options); $sql = "SELECT * from status;"; $res = & $db->query($sql); $row = null; if ($res->numRows() > 0) { $row = & $res->fetchRow(MDB2_FETCHMODE_ASSOC); $current_status = $row['status']; } $final_image = null; //Only try to print images if its likely that you will be able to. if ($current_status == "inprogress" || $current_status == "results" || $current_status == "postelection") { //Check to see if the image is pre-cached if its not, or its not pre-cached //for the right election step, we'll reproduce it and then save it. //Image Name == BallotID+StatusTableTimestamp+(Zoom*100).png $bname = "ballotimages/" . $bid . date('YmdHis', $row['stamp']) . ($zoom*100) . ".png"; $im = LoadPNG($bname); $im = null; //If null as expected, go ahead and generate the image. if ($im == null) { //$final_image = PrintErrorImage($bname); //Debug line //Load generic ballot information /** * Note: Right now, this is static, that should change.. * what is needed is a list of ballot properties that may change each * election, but not during one **/ //These could be called "required" ballot properties, if we had //Ballot properties which were not required, we could simply //abstract it away in a DB that contains "content", x, and y.. // or something of that nature. $expected_width = 1224; $expected_height = 2016; $bsnx = 980; $bsny = 75; $bsnboty = 50; $top_filename = "graphics/top.png"; $bot_filename = "graphics/bottom.png"; $dot_filename = "graphics/dot.png"; $serialnumber_font = "/web/private/TENHB192.TTF"; $bsn_fontsize = 20; //These are usually a function of dot size, so might change in future.. $dot_offset_x = 0; $dot_offset_y = 0; //Local Vars $size = null; $bid = $bid . ""; //Load Choices -> Coordinate Map, Yes, this kills previous values, but we //don't really need them anymore! $sql = "SELECT ballots.bid, ballots.type, choices.qid, choices.aid, " . "choicemap.ycoord, choicemap.xcoord from ((ballots inner join " . "choices on ballots.bid = choices.bid) inner join choicemap on " . "choices.qid = choicemap.qid and choices.aid = choicemap.aid) where " . "ballots.bid = ?;"; $qry = $db->prepare($sql); $res = & $qry->execute(array($bid)); if (!PEAR::isError($res) && $res->numRows() > 0) { $row = & $res->fetchRow(MDB2_FETCHMODE_ASSOC); $type = $row['type']; //Load the right image template if ($type != "top") { $bsny = $bsnboty; $final_image = LoadPNG($bot_filename); $size = getimagesize($bot_filename); } else { $final_image = LoadPNG($top_filename); $size = getimagesize($top_filename); } //Scale factor (actual image size vs. expected) $scale_x = $size[0]/$expected_width; $scale_y = $size[1]/$expected_height; //Scale override (uncomment to disable) $expected_height = imagesy($final_image); $expected_width = imagesx($final_image); $scale_x = 1; $scale_y = 1; //Load dots $dot = LoadPNG($dot_filename); $dotsize = getimagesize($dot_filename); //Centroid //$dot_offset_x = intval((.5*$dotsize[0] + $dot_offset_x)*$scale_x); //$dot_offset_y = intval((.5*$dotsize[1] + $dot_offset_y)*$scale_y); //Copy dots into template imagecopy($final_image, $dot, $row['xcoord']*$scale_x-$dot_offset_x, $row['ycoord']*$scale_y-$dot_offset_y, 0, 0, $dotsize[0], $dotsize[1]); while ($row = & $res->fetchRow(MDB2_FETCHMODE_ASSOC)) { imagecopy($final_image, $dot, $row['xcoord']*$scale_x-$dot_offset_x, $row['ycoord']*$scale_y-$dot_offset_y, 0, 0, $dotsize[0], $dotsize[1]); } //Draw the Ballot Serial Number $bsns = $db->query("SELECT * FROM bsnmap ORDER BY digit ASC;"); $splitid = $bid . ""; $idstring = ""; $numBsns = $bsns->numRows(); $bsnx = array(); $bsny = array(); $bsn_fontsize = $bsn_fontsize*$scale_x; $black = imagecolorallocate($final_image, 0, 0, 0); $i = 0; while ($curr_row = $bsns->fetchRow(MDB2_FETCHMODE_ASSOC)) { if ($type == "top") { $bsnx = $curr_row['topx']; $bsny = $curr_row['topy']; } else { $bsnx = $curr_row['botx']; $bsny = $curr_row['boty']; } $bsnx *= $scale_x; $bsny *= $scale_y; //Enter a 0! if ($numBsns - $i > strlen($splitid)) { $idstring = "0"; } else { $idstring = $splitid[$i - $numBsns + strlen($splitid)] . ""; } imagettftext($final_image, $bsn_fontsize, 0, $bsnx, $bsny, $black, $serialnumber_font, $idstring); $i++; } //Print the letters on the ballot. if ($current_status == "results" || $current_status == "postelection") { //Determine which font to use $letter_font = "/web/private/CIRCLEB.TTF"; if ($type != "top") $letter_font = "/web/private/arial.ttf"; $letter_font = "/web/private/arial.ttf"; $sql = "SELECT * FROM charmap LEFT JOIN choicemap on charmap.qid = " . "choicemap.qid and charmap.aid = choicemap.aid where bid = ? " . "order by charmap.qid;"; $stmt = $db->prepare($sql); $lres = $stmt->execute($bid); if (PEAR::isError($lres)) { $final_image = PrintErrorImage($lres->getMessage()); } while ($ql = $lres->fetchRow(MDB2_FETCHMODE_ASSOC)) { $prefix = "top"; if ($type != "top") $prefix = ""; imagettftext($final_image, 24, 0, $scale_x*intval($ql[$prefix . "xcoord"])+20, $scale_y*intval($ql[$prefix . "ycoord"])+40, $black, $letter_font, $ql["letter"]); } } //Zoom zoom Zoom! if ($zoom != 1) { $new_width = $zoom*$size[0]; $new_height = $zoom*$size[1]; $tmp = imagecreatetruecolor($new_width, $new_height); imagecopyresampled($tmp, $final_image, 0, 0, 0, 0, $new_width, $new_height, $size[0], $size[1]); imagedestroy($final_image); //Note: Copied by reference! $final_image = &$tmp; } //Save the image to disk.. imagepng($final_image, $bname); } elseif (PEAR::isError($res)) { $final_image = PrintErrorImage($res->getMessage()); } else { $final_image = PrintErrorImage("Ballot not (yet) in database"); } } else $final_image = $im; } else { $msg = "Invalid Election Status \"$current_status\""; $final_image = PrintErrorImage($msg); } //This should never happen if ($final_image == null) $final_image = PrintErrorImage("Final image not defined!"); $db->disconnect(); //Print the image imagepng($final_image); imagedestroy($final_image); ?>