├── examples └── example.php ├── README └── src └── canto.php /examples/example.php: -------------------------------------------------------------------------------- 1 | setSource(1, 1, 1) 9 | ->paint() 10 | ->moveTo(100, 100) 11 | ->setSource(0, 0, 0) 12 | ->lineTo(200, 200, 200, 250, 100, 250, 100, 100) 13 | ->stroke() 14 | ->setSource(1, 0, 0) 15 | ->lineTo(100, 150, 150, 200) 16 | ->stroke() 17 | ->moveTo(20, 50) 18 | ->selectFont("Helvetica")->setFontSize(48) 19 | ->showText("Hello world") 20 | ->toPng(); 21 | file_put_contents('output.png', $data); 22 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Canto.PHP 2 | ========= 3 | 4 | This is a port of the canto.js library for JavaScript to PHP. It wraps 5 | around the PECL/Cairo library to add a fluent API mostly matching that 6 | of the original API. 7 | 8 | canto.js original announcement: 9 | http://www.davidflanagan.com/2010/07/cantojs-an-impr.html 10 | 11 | Repository: 12 | http://code.google.com/p/canto-js/ 13 | 14 | This PHP port is written by Michael Maclean with thanks 15 | to David Flanagan for the inspiration. 16 | 17 | 18 | Example 19 | ======= 20 | 21 | $s = new CairoImageSurface(CairoFormat::ARGB32, 400, 400); 22 | $c = new Canto($s); 23 | $data = $c->moveTo(100, 100) 24 | ->lineTo(200, 200, 200, 250, 100, 250, 100, 100) 25 | ->stroke(); 26 | -------------------------------------------------------------------------------- /src/canto.php: -------------------------------------------------------------------------------- 1 | surface = $c; 33 | $this->context = new CairoContext($this->surface); 34 | } else if ($c instanceof CairoContext) { 35 | $this->context = $c; 36 | $this->surface = $this->context->getTarget(); 37 | } else { 38 | throw new InvalidArgumentException("Canto::__construct expects either a CairoSurface or a CairoContext"); 39 | } 40 | } 41 | 42 | public function newPath() { 43 | $this->context->newPath(); 44 | return $this; 45 | } 46 | 47 | public function closePath() { 48 | $this->context->closePath(); 49 | return $this; 50 | } 51 | 52 | public function moveTo($x, $y) { 53 | $this->context->moveTo($x, $y); 54 | return $this; 55 | } 56 | 57 | public function lineTo($x, $y) { 58 | $argc = func_num_args(); 59 | 60 | if ($argc == 0 || ($argc % 2) != 0) { 61 | throw new InvalidArgumentException("Canto::moveTo expects an even number of arguments"); 62 | } 63 | 64 | $args = func_get_args(); 65 | for ($i = 0; $i < $argc; $i += 2) { 66 | $this->context->lineTo($args[$i], $args[$i + 1]); 67 | } 68 | 69 | return $this; 70 | } 71 | 72 | public function stroke(array $params = null) { 73 | $this->context->stroke(); 74 | return $this; 75 | } 76 | 77 | public function fill(array $params = null) { 78 | $this->context->fill(); 79 | return $this; 80 | } 81 | 82 | public function paint(array $params = null) { 83 | $this->context->paint(); 84 | return $this; 85 | } 86 | 87 | public function setSource($r, $g = null, $b = null, $a = null) { 88 | if ($r instanceof CairoSurface) { 89 | // We appear to be being passed a surface to use 90 | $x = $g !== null ? $g : 0; 91 | $y = $b !== null ? $b : 0; 92 | $this->context->setSourceSurface($r, $g, $b); 93 | } else if ($r instanceof CairoPattern) { 94 | // We seem to be being passed a pattern 95 | $this->context->setSource($r); 96 | } else if (is_numeric($r)) { 97 | // We appear to be given an RGB value 98 | if (is_numeric($a)) { 99 | $this->context->setSourceRGBA($r, $g, $b, $a); 100 | } else { 101 | $this->context->setSourceRGB($r, $g, $b); 102 | } 103 | } 104 | 105 | return $this; 106 | } 107 | 108 | public function selectFontFace($fontDescription) { 109 | $this->context->selectFontFace($fontDescription); 110 | return $this; 111 | } 112 | 113 | public function selectFont($fontDescription) { 114 | return $this->selectFontFace($fontDescription); 115 | return $this; 116 | } 117 | 118 | public function setFontSize($size) { 119 | $this->context->setFontSize($size); 120 | return $this; 121 | } 122 | 123 | public function showText($text) { 124 | $this->context->showText($text); 125 | return $this; 126 | } 127 | 128 | public function save() { 129 | $this->context->save(); 130 | return $this; 131 | } 132 | 133 | public function restore() { 134 | $this->context->restore(); 135 | return $this; 136 | } 137 | 138 | public function toPng($filename = null) { 139 | if ($filename != null) { 140 | $this->surface->writeToPng($filename); 141 | return $this; 142 | } else { 143 | $temp = fopen('php://temp', 'rw'); 144 | $this->surface->writeToPng($temp); 145 | $filesize = ftell($temp); 146 | rewind($temp); 147 | $pngData = fread($temp, $filesize); 148 | return $pngData; 149 | } 150 | } 151 | 152 | public function toDataUri() { 153 | $data = base64_encode($this->toPng()); 154 | return 'data:image/png;base64,' . $data; 155 | } 156 | } 157 | --------------------------------------------------------------------------------