Browse Source

Merge remote-tracking branch 'refs/remotes/origin/master'

Nathaniel van Diepen 6 years ago
parent
commit
8872facf88
2 changed files with 339 additions and 3 deletions
  1. 5 3
      Data/template.class.php
  2. 334 0
      image.class.php

+ 5 - 3
Data/template.class.php

@@ -27,7 +27,8 @@
 			'merge-divs'=>false,
 			'merge-spans'=>false,
 			'logical-emphasis'=>false,
-			'literal-attributes'=>true
+			'literal-attributes'=>true,
+			'drop-empty-elements'=>false
 		];
 		private static $regex = [
 			'getmatch'=>'/\{!([^#\/?_][^}\n]*?)\}/i',
@@ -49,7 +50,7 @@
 			'eval'=>'/\{\?([\W\w\S\s]+)\?\}/i',
 			'include'=>'/{#include ([^}]+)}/i',
 			'define'=>'/\{#define ([^}]*)\}([\S\s]*)\{\/define \1\}/i',
-			'widget'=>'/{#widget ([^ }]+)(?: ((?:[^=}]+=[^}&]+)*))?}/i'
+			'widget'=>'/{#widget ([^ }]+)(?: ((?:[^=}]+=[^}&]*)*))?}/i'
 		];
 		protected static $parsers;
 		private $template;
@@ -103,7 +104,8 @@
 									foreach(explode('&', $matches[2]) as $chunk){
 										$param = explode('=', $chunk);
 										if($param){
-											$args[urldecode($param[0])] = urldecode($param[1]);
+											$val = $param[1] ?? "";
+											$args[urldecode($param[0])] = urldecode($val);
 										}
 									}
 									$widget = "<?php \$widget_parent[] = \$data; \$data = array_merge(json_decode(json_encode(\$data), true), json_decode(base64_decode(".var_export(base64_encode(json_encode($args)), true)."), true)); ?>";

+ 334 - 0
image.class.php

@@ -0,0 +1,334 @@
+<?php
+	namespace Juju;
+	class Image implements \JsonSerializable{
+		private $img;
+		private $actions = array();
+		private $colours = array();
+		protected $width;
+		protected $height;
+		protected $background;
+		protected $type;
+		public function __construct($width,$height,$background='white',$type='png'){
+			$this->img = imagecreatetruecolor($width,$height);
+			if(!$this->img){
+				throw new Exception('Could not create image');
+			}
+			if(function_exists('imageantialias')){
+				imageantialias($this->img,true);
+			}
+			$this->width = $width;
+			$this->height = $height;
+			$this->colour('black',0,0,0);
+			$this->colour('white',255,255,255);
+			$this->colour('red',255,0,0);
+			$this->colour('green',0,255,0);
+			$this->colour('blue',0,0,255);
+			$this->background = $background;
+			$this->type = $type;
+		}
+		public function __get($name){
+			switch($name){
+				case 'width':
+					return $this->width;
+				break;
+				case 'height':
+					return $this->height;
+				break;
+				case 'type':
+					return $this->type;
+				break;
+				case 'background':
+					return $this->background;
+				break;
+				case 'actions':
+					return $this->actions;
+				break;
+			}
+		}
+		public function __clone(){
+			$this->img = clone $this->img;
+		}
+		public function __destruct(){
+			imagedestroy($this->img);
+		}
+		public function jsonSerialize(){
+			return array(
+				'width'=>$this->width,
+				'height'=>$this->height,
+				'type'=>$this->type,
+				'data'=>'data:image/'.$this->type.';base64,'.base64_encode($this->toData())
+			);
+		}
+		public function toData(){
+			ob_start();
+			$this();
+			$data = ob_get_contents();
+			ob_end_clean();
+			return $data;
+		}
+		public function __toString(){
+			return '[Image Object ('.$this->width.','.$this->height.')]';
+		}
+		public function __invoke(){
+			$this->render();
+			$args = array_merge(array($this->img),func_get_args());
+			return call_user_func_array('image'.$this->type,$args);
+		}
+		public function render(){
+			imagefill($this->img,0,0,$this->colour($this->background));
+			for($k=0;$k<count($this->actions);$k++){
+				$a = $this->actions[$k];
+				switch($a[0]){
+					case 'text':
+						imagestring(
+							$this->img,
+							$a[5],
+							$a[2],
+							$a[3],
+							$a[1],
+							$this->color($a[4])
+						);
+					break;
+					case 'vertical_text':
+						imagestringup(
+							$this->img,
+							$a[5],
+							$a[2],
+							$a[3],
+							$a[1],
+							$this->color($a[4])
+						);
+					break;
+					case 'line':
+						imageline(
+							$this->img,
+							$a[1],$a[2],
+							$a[3], $a[4],
+							$this->color($a[5])
+						);
+					break;
+					case 'rectangle':
+						imagerectangle(
+							$this->img,
+							$a[1],$a[2],
+							$a[3],$a[4],
+							$this->color($a[5])
+						);
+					break;
+					case 'filled_rectangle':
+						imagefilledrectangle(
+							$this->img,
+							$a[1],$a[2],
+							$a[3],$a[4],
+							$this->color($a[5])
+						);
+					break;
+					case 'polygon':
+						imagepolygon(
+							$this->img,
+							$a[1],
+							count($a[1])/2,
+							$this->colour($a[2])
+						);
+					break;
+					case 'filled_polygon':
+						imagefilledpolygon(
+							$this->img,
+							$a[1],
+							count($a[1])/2,
+							$this->colour($a[2])
+						);
+					break;
+					case 'arc':
+						imagearc(
+							$this->img,
+							$a[1],$a[2],
+							$a[3],$a[4],
+							$a[5],$a[6],
+							$this->colour($a[7])
+						);
+					break;
+					case 'filled_arc':
+						imagefilledarc(
+							$this->img,
+							$a[1],$a[2],
+							$a[3],$a[4],
+							$a[5],$a[6],
+							$this->colour($a[7]),
+							$a[8]
+						);
+					break;
+					case 'ellipse':
+						imageellipse(
+							$this->img,
+							$a[1],$a[2],
+							$a[3],$a[4],
+							$this->colour($a[5])
+						);
+					break;
+					case 'filled_ellipse':
+						imagefilledellipse(
+							$this->img,
+							$a[1],$a[2],
+							$a[3],$a[4],
+							$this->colour($a[5])
+						);
+					break;
+					case 'flood_fill':
+						imagefilltoborder(
+							$this->img,
+							$a[1],$a[2],
+							$this->colour($a[3]),
+							$this->colour($a[4])
+						);
+					break;
+					case 'filter':
+						$args = array_merge(array($this->img),$a[1]);
+						call_user_func_array('imagefilter',$args);
+					break;
+				}
+			}
+			return $this;
+		}
+		public function color(){
+			return call_user_func_array(array($this, 'colour'),func_get_args());
+		}
+		public function colour(){
+			if(func_num_args() > 1){
+				if(!isset($this->colours[func_get_arg(0)])){
+					$this->colours[func_get_arg(0)] = imagecolorallocate($this->img,func_get_arg(1),func_get_arg(2),func_get_arg(3));
+				}
+			}
+			return $this->colours[func_get_arg(0)];
+		}
+		public function text($text,$x,$y,$colour='white',$size=1){
+			array_push($this->actions,array(
+				'text',
+				$text,
+				$x,$y,
+				$colour,
+				$size
+			));
+			return $this;
+		}
+		public function vertical_text($text,$x,$y,$colour='white',$size=1){
+			array_push($this->actions,array(
+				'vertical_text',
+				$text,
+				$x,$y,
+				$colour,
+				$size
+			));
+			return $this;
+		}
+		public function line($x1,$y1,$x2,$y2,$colour){
+			array_push($this->actions,array(
+				'line',
+				$x1,$y1,
+				$x2,$y2,
+				$colour
+			));
+			return $this;
+		}
+		public function polygon($points,$colour){
+			array_push($this->actions,array(
+				'polygon',
+				$points,
+				$colour
+			));
+			return $this;
+		}
+		public function filled_polygon($points,$colour){
+			array_push($this->actions,array(
+				'filled_polygon',
+				$points,
+				$colour
+			));
+			return $this;
+		}
+		public function rectangle($x1,$y1,$x2,$y2,$colour){
+			array_push($this->actions,array(
+				'rectangle',
+				$x1,$y1,
+				$x2,$y2,
+				$colour
+			));
+			return $this;
+		}
+		public function filled_rectangle($x1,$y1,$x2,$y2,$colour){
+			array_push($this->actions,array(
+				'filled_rectangle',
+				$x1,$y1,
+				$x2,$y2,
+				$colour
+			));
+			return $this;
+		}
+		public function arc($cx,$cy,$w,$h,$sa,$ea,$colour){
+			array_push($this->actions,array(
+				'arc',
+				$cx,$cy,
+				$w,$h,
+				$sa,$ea,
+				$colour
+			));
+			return $this;
+		}
+		public function filled_arc($cx,$cy,$w,$h,$sa,$ea,$colour,$style=IMG_ARC_PIE){
+			array_push($this->actions,array(
+				'filled_arc',
+				$cx,$cy,
+				$w,$h,
+				$sa,$ea,
+				$colour,
+				$style
+			));
+			return $this;
+		}
+		public function ellipse($cx,$cy,$w,$h,$colour){
+			array_push($this->actions,array(
+				'ellipse',
+				$cx,$cy,
+				$w,$h,
+				$colour
+			));
+			return $this;
+		}
+		public function circle($cx,$cy,$w,$colour){
+			return $this->ellipse($cx,$cy,$w,$w,$colour);
+		}
+		public function filled_ellipse($cx,$cy,$w,$h,$colour){
+			array_push($this->actions,array(
+				'filled_ellipse',
+				$cx,$cy,
+				$w,$h,
+				$colour
+			));
+			return $this;
+		}
+		public function filled_circle($cx,$cy,$w,$colour){
+			return $this->filled_ellipse($cx,$cy,$w,$w,$colour);
+		}
+		public function flood_fill($x,$y,$border_colour,$colour){
+			array_push($this->actions,array(
+				'flood_fill',
+				$x,$y,
+				$border_colour,
+				$colour
+			));
+			return $this;
+		}
+		public function filter(){
+			array_push($this->actions,array(
+				'filter',
+				func_get_args()
+			));
+			return $this;
+		}
+		public function copy($dest){
+			$this->render();
+			imagepalettecopy($dest,$this->img);
+			return $this;
+		}
+	}
+?>