102 lines
3 KiB
PHP
102 lines
3 KiB
PHP
<?php
|
|
|
|
namespace swf2ass;
|
|
|
|
|
|
use MartinezRueda\Algorithm;
|
|
use MartinezRueda\Polygon;
|
|
|
|
class ClipPath {
|
|
/** @var Shape[] */
|
|
public array $shapes;
|
|
|
|
|
|
/**
|
|
* @param Shape[] $shapes
|
|
*/
|
|
public function __construct(array $shapes = []){
|
|
$this->shapes = $shapes;
|
|
}
|
|
|
|
public function getShape() : Shape{
|
|
$shape = new Shape();
|
|
foreach ($this->shapes as $s){
|
|
$shape = $shape->merge($s);
|
|
}
|
|
return $shape;
|
|
}
|
|
|
|
public function addShape(Shape $shape){
|
|
$this->shapes[] = $shape;
|
|
}
|
|
|
|
|
|
/**
|
|
* Calculates the intersection between two ClipPath.
|
|
* Shapes part of the clips need to be flat (or they will be flattened)
|
|
*
|
|
* @param ClipPath $other
|
|
* @return ClipPath
|
|
*/
|
|
public function intersect(ClipPath $other) : ClipPath{
|
|
try{
|
|
return self::fromPolygon((new Algorithm())->getIntersection($this->toPolygon(), $other->toPolygon()));
|
|
}catch (\Exception $e){
|
|
var_dump($this);
|
|
var_dump($other);
|
|
echo $e;
|
|
$self = $this->getShape()->flatten();
|
|
$other = $other->getShape()->flatten();
|
|
var_dump((new Shape($self->getRecords()))->getArea());
|
|
var_dump((new \swf2ass\ass\drawTag(new Shape($self->getRecords()), 1))->encode(new \swf2ass\ass\ASSEventTime(1, 1, 1)));
|
|
var_dump((new Shape($other->getRecords()))->getArea());
|
|
var_dump((new \swf2ass\ass\drawTag(new Shape($other->getRecords()), 1))->encode(new \swf2ass\ass\ASSEventTime(1, 1, 1)));
|
|
return $this; //TODO: fix this breakage, some clips being overlapping shapes????
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private function toPolygon() : Polygon{
|
|
$contours = [];
|
|
foreach ($this->shapes as $shape){
|
|
$contours[] = array_map(function (Vector2 $point){return $point->toArray();}, $shape->toPoints());
|
|
}
|
|
return new Polygon($contours);
|
|
}
|
|
|
|
|
|
private static function fromPolygon(Polygon $p) : ClipPath{
|
|
$result = $p->toArray();
|
|
|
|
$clipPath = new ClipPath();
|
|
if(count($result) === 0){ //Nothing!
|
|
return $clipPath;
|
|
}
|
|
|
|
foreach ($result as $contour){
|
|
$shape = new Shape();
|
|
$start = $pos = new Vector2(...reset($contour));
|
|
while (($p = next($contour)) !== false){
|
|
$point = new Vector2(...$p);
|
|
$shape->addRecord(new LineRecord($point, $pos));
|
|
$pos = $point;
|
|
}
|
|
|
|
//if($shape->getArea() > Constants::EPSILON){ //TODO
|
|
$shape->addRecord(new LineRecord($start, $pos)); //Close shape
|
|
$clipPath->addShape($shape);
|
|
//}
|
|
}
|
|
|
|
return $clipPath;
|
|
}
|
|
|
|
public function applyMatrixTransform(MatrixTransform $transform, bool $applyTranslation = true) : ClipPath{
|
|
$shapes = [];
|
|
foreach ($this->shapes as $shape){
|
|
$shapes[] = $transform->applyToShape($shape, $applyTranslation);
|
|
}
|
|
return new ClipPath($shapes);
|
|
}
|
|
} |