Last active
March 26, 2023 05:58
-
-
Save SerafimArts/01be7b01e9d1186fc7bf to your computer and use it in GitHub Desktop.
AI (Adobe Illustrator) Reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace app\support\lib; | |
class Rect | |
{ | |
protected $left; | |
protected $top; | |
protected $width; | |
protected $height; | |
public function __construct($left, $top, $width, $height) | |
{ | |
$this->left = $left; | |
$this->top = $top; | |
$this->width = $width; | |
$this->height = $height; | |
} | |
public function getSize() | |
{ | |
return (object)[ | |
'width' => $this->width - $this->left, | |
'height' => $this->height - $this->top | |
]; | |
} | |
public function __get($var) | |
{ | |
if (isset($this->$var)) { | |
return $this->$var; | |
} | |
return null; | |
} | |
} | |
class Operation | |
{ | |
/** | |
* @url http://partners.adobe.com/public/developer/en/illustrator/sdk/AI7FileFormat.pdf (page 56+) | |
* | |
* @TODO | |
* operation l | |
* operation L | |
* operation C | |
* operation V | |
* operation Y | |
*/ | |
const OP_MOVE = 'm'; | |
const OP_BEZIER = 'c'; | |
const OP_BEZIER_SEGMENT_TO = 'v'; | |
const OP_BEZIER_SEGMENT_FROM = 'y'; | |
protected $type; | |
protected $points = []; | |
public function __construct($operation) | |
{ | |
$points = explode(' ', $operation); | |
$this->type = array_pop($points); | |
foreach ($points as $point) { | |
$this->points[] = (double)$point; | |
} | |
} | |
} | |
class Layer | |
{ | |
protected $operations = []; | |
protected $overlays = []; | |
public function __construct($points, $overlays) | |
{ | |
$operations = explode(chr(13), $points); | |
foreach ($operations as $op) { | |
if (trim($op)) { | |
$this->operations[] = new Operation(trim($op)); | |
} | |
} | |
preg_match_all('#\/([a-z]+)\s+((?:\/)?[a-z]+)\s*#isu', $overlays, $m); | |
for ($i=0; $i<count($m[0]); $i++) { | |
$this->overlays[$m[1][$i]] = $m[2][$i]; | |
} | |
} | |
} | |
class Ai | |
{ | |
protected $title; | |
protected $creator; | |
protected $path; | |
protected $layers; | |
public static function createFromFile($file) | |
{ | |
return new static(file_get_contents($file)); | |
} | |
public static function createFromSources($sources) | |
{ | |
return new static($sources); | |
} | |
public function __construct($sources) | |
{ | |
$this->title = $this->parse($sources, 'Title'); | |
$this->creator = $this->parse($sources, 'Creator'); | |
$this->path = $this->readSizes($sources); | |
$this->layers = $this->readLayers($sources); | |
} | |
public function getTitle() | |
{ | |
return $this->title; | |
} | |
public function getCreator() | |
{ | |
return $this->creator; | |
} | |
public function getPath() | |
{ | |
return $this->path; | |
} | |
public function getLayers() | |
{ | |
return $this->layers; | |
} | |
protected function readSizes($sources) | |
{ | |
$box = explode(' ', $this->parse($sources, 'BoundingBox')); | |
return new Rect($box[0], $box[1], $box[2], $box[3]); | |
} | |
protected function readLayers($sources) | |
{ | |
$result = []; | |
$pattern = '#%AI[0-9]+_Note:<<\s(.*?)\s>>\r1\sXR\s*(.*?)\s*n\r\*U#isu'; | |
preg_match_all($pattern, $sources, $layers); | |
for ($i=0; $i<count($layers[0]); $i++) { | |
$result[] = new Layer($layers[2][$i], $layers[1][$i]); | |
} | |
return $result; | |
} | |
protected function parse($sources, $meta) | |
{ | |
$pattern = '#%%' . $meta . ':(.*?)\r#isu'; | |
preg_match_all($pattern, $sources, $m); | |
if (isset($m[1][0])) { | |
return trim($m[1][0]); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@reasecret just like without it.