Пример #1
0
 public function output($save_as = null, &$format = null)
 {
     $output_format = 'SVG';
     if (isset($_SERVER['HTTP_USER_AGENT']) || isset($_REQUEST['force_format'])) {
         static $browser_renderer = null;
         if (isset($_REQUEST['force_format'])) {
             // Don't nest the force_format within the browser_renderer null check in case its overriden by OpenBenchmarking.org dynamically
             $output_format = $_REQUEST['force_format'];
         } else {
             if ($browser_renderer == null) {
                 $output_format = pts_render::renderer_compatibility_check($_SERVER['HTTP_USER_AGENT']);
             } else {
                 $output_format = $browser_renderer;
             }
         }
     }
     $format = $output_format;
     switch ($output_format) {
         case 'JPG':
         case 'JPEG':
             $output = pts_svg_dom_gd::svg_dom_to_gd($this->dom, 'JPEG');
             $output_format = 'jpg';
             break;
         case 'PNG':
             $output = pts_svg_dom_gd::svg_dom_to_gd($this->dom, 'PNG');
             $output_format = 'png';
             break;
         case 'SVG':
         default:
             $output = $this->save_xml();
             $output_format = 'svg';
             break;
     }
     if ($output == null) {
         return false;
     } else {
         if ($save_as) {
             return file_put_contents(str_replace('BILDE_EXTENSION', $output_format, $save_as), $output);
         } else {
             return $output;
         }
     }
 }
 public static function svg_dom_to_gd($dom, $format)
 {
     if (extension_loaded('gd') && function_exists('imagettftext') && $dom->childNodes->item(2)->nodeName == 'svg') {
         $width = $dom->childNodes->item(2)->attributes->getNamedItem('width')->nodeValue;
         $height = $dom->childNodes->item(2)->attributes->getNamedItem('height')->nodeValue;
         if ($width > 1 && $height > 1) {
             $gd = imagecreatetruecolor($width, $height);
             if (!isset($_REQUEST['svg_dom_gd_no_interlacing'])) {
                 // PHP FPDF fails on image interlacing
                 imageinterlace($gd, true);
             }
             if (function_exists('imageantialias')) {
                 imageantialias($gd, true);
             }
         } else {
             return false;
         }
         //foreach($dom->childNodes->item(2)->attributes  as $atrr)
         //	{ echo $atrr->name . ' ' . $atrr->value . PHP_EOL; }
     } else {
         // If the first tag isn't an svg tag, chances are something is broke...
         return false;
     }
     self::$color_table = array();
     foreach ($dom->childNodes->item(2)->childNodes as $node) {
         self::evaluate_node($node, $gd);
         // imagejpeg($this->image, $output_file, $quality);
         //var_dump($node->attributes);
     }
     $tmp_output = tempnam('/tmp', 'pts-gd');
     switch ($format) {
         case 'JPEG':
             imagejpeg($gd, $tmp_output, 100);
             $output = file_get_contents($tmp_output);
             unlink($tmp_output);
             break;
         case 'PNG':
             imagepng($gd, $tmp_output, 1);
             $output = file_get_contents($tmp_output);
             unlink($tmp_output);
             break;
     }
     return $output;
 }
 public static function svg_dom_to_gd($dom, $format)
 {
     if (extension_loaded('gd') && function_exists('imagettftext') && $dom->childNodes->item(2)->nodeName == 'svg') {
         $width = $dom->childNodes->item(2)->attributes->getNamedItem('width')->nodeValue;
         $height = $dom->childNodes->item(2)->attributes->getNamedItem('height')->nodeValue;
         if ($width > 1 && $height > 1) {
             $gd = imagecreatetruecolor($width, $height);
             if (!isset($_REQUEST['svg_dom_gd_no_interlacing'])) {
                 // PHP FPDF fails on image interlacing
                 imageinterlace($gd, true);
             }
             if (function_exists('imageantialias')) {
                 imageantialias($gd, true);
             }
         } else {
             return false;
         }
         //foreach($dom->childNodes->item(2)->attributes  as $atrr)
         //	{ echo $atrr->name . ' ' . $atrr->value . PHP_EOL; }
     } else {
         // If the first tag isn't an svg tag, chances are something is broke...
         return false;
     }
     self::$color_table = array();
     foreach ($dom->childNodes->item(2)->childNodes as $node) {
         if ($node->nodeName == 'a') {
             // This is just a link so get whatever is the child of the embedded link to display
             $node = $node->childNodes->item(0);
         }
         switch ($node->nodeName) {
             case 'svg':
                 // Not relevant at this point to GD rendering
                 break;
             case 'line':
                 $a = self::attributes_to_array($node, array('x1', 'y1', 'x2', 'y2', 'stroke', 'stroke-width', 'stroke-dasharray'));
                 $line_color = self::gd_color_allocate($gd, $a['stroke']);
                 if ($a['stroke-dasharray'] != null) {
                     list($dash_length, $blank_length) = explode(',', $a['stroke-dasharray']);
                     if ($a['y1'] == $a['y2']) {
                         for ($i = $a['x1']; $i < $a['x2']; $i += $blank_length + $dash_length) {
                             imagefilledrectangle($gd, $i, $a['y1'] - floor($a['stroke-width'] / 2), $i + $dash_length, $a['y1'] + floor($a['stroke-width'] / 2), $line_color);
                             //imageline($gd, $i, $pos, ($i + $dash_length), $pos, $line_color);
                         }
                     } else {
                         for ($i = $a['y1']; $i < $a['y2']; $i += $blank_length + $dash_length) {
                             imagefilledrectangle($gd, $a['x1'] - floor($a['stroke-width'] / 2), $i, $a['x1'] + floor($a['stroke-width'] / 2), $i + $dash_length, $line_color);
                             //imageline($gd, $i, $pos, ($i + $dash_length), $pos, $line_color);
                         }
                     }
                 } else {
                     imagesetthickness($gd, $a['stroke-width']);
                     imageline($gd, $a['x1'], $a['y1'], $a['x2'], $a['y2'], $line_color);
                 }
                 break;
             case 'polyline':
                 $a = self::attributes_to_array($node, array('points', 'stroke', 'stroke-width', 'fill'));
                 imagesetthickness($gd, $a['stroke-width']);
                 $line_color = self::gd_color_allocate($gd, $a['stroke']);
                 $a['points'] = explode(' ', $a['points']);
                 for ($i = 1; $i < count($a['points']); $i++) {
                     $s_point = explode(',', $a['points'][$i - 1]);
                     $e_point = explode(',', $a['points'][$i]);
                     imageline($gd, $s_point[0], $s_point[1], $e_point[0], $e_point[1], $line_color);
                 }
                 break;
             case 'text':
                 $a = self::attributes_to_array($node, array('x', 'y', 'font-size', 'text-anchor', 'fill', 'dominant-baseline', 'transform'));
                 $text = $node->nodeValue;
                 $a['font-size'] -= 1.6;
                 $box_array = imagettfbbox($a['font-size'], 0, self::$default_font, $text);
                 $box_width = $box_array[4] - $box_array[6];
                 $box_height = $box_array[1] - $box_array[7];
                 $rotate = 0;
                 if ($a['transform']) {
                     $rotate = substr($a['transform'], 7);
                     $rotate = substr($rotate, 0, strpos($rotate, ' '));
                     // $rotate this should be the rotation degree in SVG
                     if ($rotate != 0) {
                         $rotate += 180;
                     }
                     switch ($a['text-anchor']) {
                         case 'middle':
                             $a['y'] -= round($box_width / 2);
                             break;
                     }
                 } else {
                     switch ($a['text-anchor']) {
                         case 'start':
                             break;
                         case 'middle':
                             $a['x'] -= round($box_width / 2);
                             break;
                         case 'end':
                             $a['x'] -= $box_width - 4;
                             break;
                     }
                     switch ($a['dominant-baseline']) {
                         case 'text-before-edge':
                             $a['y'] += $box_height;
                             break;
                         case 'middle':
                             $a['y'] += round($box_height / 2);
                             break;
                     }
                 }
                 imagettftext($gd, $a['font-size'], $rotate, $a['x'], $a['y'], self::gd_color_allocate($gd, $a['fill']), self::$default_font, $text);
                 break;
             case 'polygon':
                 $a = self::attributes_to_array($node, array('points', 'fill', 'stroke', 'stroke-width'));
                 $a['points'] = explode(' ', $a['points']);
                 $points = array();
                 foreach ($a['points'] as &$point) {
                     $point = explode(',', $point);
                     array_push($points, $point[0]);
                     array_push($points, $point[1]);
                 }
                 if ($a['stroke-width']) {
                     imagesetthickness($gd, $a['stroke-width']);
                     imagefilledpolygon($gd, $points, count($a['points']), self::gd_color_allocate($gd, $a['stroke']));
                 }
                 imagefilledpolygon($gd, $points, count($a['points']), self::gd_color_allocate($gd, $a['fill']));
                 break;
             case 'rect':
                 // Draw a rectangle
                 $a = self::attributes_to_array($node, array('x', 'y', 'width', 'height', 'fill', 'stroke', 'stroke-width'));
                 if ($a['fill'] != 'none') {
                     imagefilledrectangle($gd, $a['x'], $a['y'], $a['x'] + $a['width'], $a['y'] + $a['height'], self::gd_color_allocate($gd, $a['fill']));
                 }
                 if ($a['stroke'] != null) {
                     // TODO: implement $a['stroke-width']
                     imagerectangle($gd, $a['x'], $a['y'], $a['x'] + $a['width'], $a['y'] + $a['height'], self::gd_color_allocate($gd, $a['stroke']));
                 }
                 break;
             case 'circle':
                 // Draw a circle
                 $a = self::attributes_to_array($node, array('cx', 'cy', 'r', 'fill'));
                 imagefilledellipse($gd, $a['cx'], $a['cy'], $a['r'] * 2, $a['r'] * 2, self::gd_color_allocate($gd, $a['fill']));
                 break;
             case 'ellipse':
                 // Draw a ellipse/circle
                 $a = self::attributes_to_array($node, array('cx', 'cy', 'rx', 'ry', 'fill', 'stroke', 'stroke-width'));
                 imagefilledellipse($gd, $a['cx'], $a['cy'], $a['rx'] * 2, $a['ry'] * 2, self::gd_color_allocate($gd, $a['fill']));
                 if ($a['stroke'] != null) {
                     // TODO: implement $a['stroke-width']
                     imagefilledellipse($gd, $a['cx'], $a['cy'], $a['rx'] * 2, $a['ry'] * 2, self::gd_color_allocate($gd, $a['stroke']));
                 }
                 break;
             case 'image':
                 $a = self::attributes_to_array($node, array('xlink:href', 'x', 'y', 'width', 'height'));
                 if (substr($a['xlink:href'], 0, 22) == 'data:image/png;base64,') {
                     $img = imagecreatefromstring(base64_decode(substr($a['xlink:href'], 22)));
                 } else {
                     $img = imagecreatefromstring(file_get_contents($a['xlink:href']));
                 }
                 imagecopyresampled($gd, $img, $a['x'], $a['y'], 0, 0, $a['width'], $a['height'], imagesx($img), imagesy($img));
                 break;
             default:
                 if (PTS_IS_CLIENT) {
                     echo $node->nodeName . ' not implemented.' . PHP_EOL;
                 }
                 break;
         }
         // imagejpeg($this->image, $output_file, $quality);
         //var_dump($node->attributes);
     }
     $tmp_output = tempnam('/tmp', 'pts-gd');
     switch ($format) {
         case 'JPEG':
             imagejpeg($gd, $tmp_output, 100);
             $output = file_get_contents($tmp_output);
             unlink($tmp_output);
             break;
         case 'PNG':
             imagepng($gd, $tmp_output, 1);
             $output = file_get_contents($tmp_output);
             unlink($tmp_output);
             break;
     }
     return $output;
 }